zoukankan      html  css  js  c++  java
  • 汇编学习--第十一天

    3.数值显示

    实际上,方法就是,数值除10,取余数,就得到数值的每一位,再观察得到,数字xH(x=0,1...9)对应,十进制数字30H+xH

    assume cs:code
    data segment
        dw 123,12666,1,8,3,38
    data ends
    code segment
    start:    mov ax,data
            mov ds,ax
            mov ax,2000h
            mov es,ax
            
            mov si,0;表示数据段中的偏移地址
            mov di,0;将16进制数存储为10进制字符的偏移地址
            mov cx,6
            
            ;循环取出数据段中的数据
    s:        mov ax,ds:[si]
            call show_str
            add si,2
            loop s
            
            mov ax,4c00h
            int 21h
            
    show_str:    push cx
                mov bp,0;bp记录入栈次数
                
                ;方法:将该数除以10,得到的余数就是该数的一位数
                ;注意,我们判断数字转换结束的条件是商为0,但是loop是先减cx,再判断,所以需要inc cx
                ;处理一个16进制数,将每一位转换为10进制字符,压入栈中
                ;压栈原因:因为得到的数据是逆序的,所以需要入栈,再出栈,得到顺序的数
    s0:            mov dx,0
                mov bx,10
                div bx
                mov cx,ax
                inc cx
                add dx,30h;数字转字符
                push dx;转换的数据入栈
                inc bp
                loop s0
                
                ;将栈中的数据取出,存储到指定位置
                mov cx,bp
                mov bx,0
    store_str:    pop dx
                mov byte ptr es:[di],dl
                inc di
                loop store_str
    
                pop cx
                inc di;这里di表示每个10进制字符之间有个间隙,方便查看
                ret
                
    code ends
    end start

    让显示这些数值,实际上就是上个程序,储存位置变成了显示缓冲区

    assume cs:code
    data segment
        dw 123,12666,1,8,3,38
    data ends
    code segment
    start:    mov ax,data
            mov ds,ax
            mov ax,0b800h
            mov es,ax
            
            mov si,0;表示数据段中的偏移地址
            mov di,0;将16进制数存储为10进制字符的偏移地址
            mov cx,6
            
            ;循环取出数据段中的数据
    s:        mov ax,ds:[si]
            call show_str
            add si,2
            loop s
            
            mov ax,4c00h
            int 21h
            
    show_str:    push cx
                mov bp,0
                
                ;方法:将该数除以10,得到的余数就是该数的一位数
                ;注意,我们判断数字转换结束的条件是商为0,但是loop是先减cx,再判断,所以需要inc cx
                ;处理一个16进制数,将每一位转换为10进制字符,压入栈中
                ;压栈原因:因为得到的数据是逆序的,所以需要入栈,再出栈,得到顺序的数
    s0:            mov dx,0
                mov bx,10
                div bx
                mov cx,ax
                inc cx
                add dx,30h;数字转字符
                push dx;转换的数据入栈
                inc bp
                loop s0
                
                ;将栈中的数据取出,存储到显示缓冲区
                mov cx,bp
                mov bx,0
    store_str:    pop dx
                mov byte ptr es:[di+500h+4],dl;低位数据,500h表示显示器第8行,4表示第3列
                mov byte ptr es:[di+500h+4+1],2;高位属性,2就是00000010,绿色
                add di,2
                loop store_str
    
                pop cx
                add di,2;方便查看
                ret
                
    code ends
    end start

    这个程序中,s0部分对应着dtoc子程序(十六进制转换为十进制字符),show_str子程序对应着store_str部分

    课程设计 1

    程序主要由三部分构成主程序,两个子程序。

    两个子程序包含字符输出,存储的子程序和dword除法

    第一个子程序功能:

    1. 将寄存器中的16进制数字转换为10进制字符数字(这里实际上就是调用第二个子程序,获得数据每一位的值),压入栈中
    2. 将栈中的字符数字依次出栈,存入指定位置的显示缓冲区

    第二个子程序功能:(来自:2.解决除法溢出

    • 计算dword型数据除10的结果,余数就是数据的每一位

    主程序流程:(整体框架来自:实验 7)

    1. 获取数据段数据,保存到指定寄存器,利用第一个子程序功能存入显示缓存区。
    2. 平均工资,先获取数据段中的总工资和人数,计算出平均工资,并存入指定寄存区,最后调用第一个子程序存入显示缓冲区。
      1 assume cs:code,ds:data,es:table
      2 
      3 data segment
      4 db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
      5 db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
      6 db '1993','1994','1995'
      7 ;以上是表示21年的字符串 4 * 21 = 84
      8 
      9 dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
     10 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
     11 ;以上是表示21年公司总收入的dword型数据 4 * 21 = 84
     12 
     13 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
     14 dw 11542,14430,15257,17800
     15 ;以上是表示21年公司雇员人数的21个word型数据 2 * 21 = 42
     16 data ends
     17 
     18 table segment
     19 db 21 dup ('year summ ne ?? ') ; 'year summ ne ?? ' 刚好16个字节
     20 table ends
     21 
     22 stack segment
     23     dw 8 dup (0)
     24 stack ends
     25 
     26 code segment
     27 start:        mov ax,data
     28             mov ds,ax
     29             mov ax,0b800h
     30             mov es,ax
     31             mov ax,stack
     32             mov ss,ax
     33             mov sp,16
     34         
     35             mov cx,21    ;外层循环每一年的情况
     36             mov bx,0a0h    ;表示第几年的情况
     37             mov di,0    ;存储年份地址
     38         
     39             mov bp,0    ;1.获取到data段中雇员数数据 2.保存bx的值
     40 s0:    push cx    
     41         mov cx,4
     42         mov si,0    ;表示这一年中的第几个
     43         
     44         ;年份
     45 s:      mov al,ds:[di];一位一位保存字符
     46         mov es:[bx+si],al
     47         mov byte ptr es:[bx+si+1],2
     48         
     49         add si,2
     50         inc di
     51         loop s
     52         add si,2
     53       
     54        ;收入
     55        mov dx,ds:[di+52h]
     56        mov ax,ds:[di+50h]
     57        mov si,24;指定列的位置,13列
     58        call show_str
     59         
     60         ;雇员数
     61         mov ax,ds:[bp+0a8h]
     62         mov dx,0
     63         mov si,44;指定列的位置,23列
     64         call show_str
     65         
     66         ;人均收入
     67         mov dx,ds:[di+52h]
     68         mov ax,ds:[di+50h]
     69         push bx
     70         mov bx,ds:[bp+0a8h]
     71         div bx
     72         mov dx,0
     73         pop bx;顺序不能变
     74         mov si,64;指定列的位置,33列
     75         call show_str
     76         
     77         pop cx
     78         add bp,2
     79         add bx,0a0h
     80         loop s0
     81         
     82         mov ax,4c00h
     83         int 21h
     84 
     85 ;调用divdw子程序(除10),获取余数(数据段数据的16进制形式)
     86 ;将余数转换为10进制字符,入栈
     87 ;循环上面操 88 ;判断结束条件:因为被除数为dword形式,需要先判断dx(高16位)是否为0,再判断ax(低16位)是否0
     89 show_str:push bp
     90         push bx
     91         
     92             mov bp,0
     93 
     94 s1:         
     95         mov cx,0ah
     96         call divdw
     97         add cx,30h;数字转字符
     98         push cx;转换的数据入栈
     99         mov cx,dx
    100         inc cx
    101         inc bp
    102         loop s1
    103             
    104         mov cx,ax
    105         inc cx
    106         loop s1
    107             
    108         ;获取表示行的数值bx,在栈中的位置的偏移地址
    109         mov cx,bp;在bx上入了多少次栈
    110         mov bx,sp;现在的栈顶
    111 s3:    add bx,2;找到bx的位置
    112         loop s3
    113         mov cx,bp
    114             
    115        mov bx,ss:[bx]
    116 store_str:    
    117             pop dx
    118             mov byte ptr es:[bx+si],dl;低位数据,500h表示显示器第8行,4表示第3列
    119             mov byte ptr es:[bx+si+1],2;高位属性,2就是00000010,绿色
    120             add si,2
    121             loop store_str
    122         
    123             pop bx
    124             pop bp
    125             add si,2
    126             ret
    127             
    128 divdw: push ax
    129           ;高16位计算
    130           mov ax, dx
    131           mov dx, 0 
    132           div cx
    133           mov bx, ax
    134           ;低16位计算
    135           pop ax
    136           div cx
    137          ;低16位
    138           mov cx, dx
    139           ;余数
    140           mov dx, bx 
    141           ret
    142 code ends
    143 end start

  • 相关阅读:
    利用fstream进行文件拷贝测试
    gcc下inline的一个问题
    链接选项-rpath的一个问题记录
    OpenCV学习代码记录——人脸检测
    OpenCV学习代码记录—— Snake轮廓
    OpenCV学习代码记录——Hough线段检测
    OpenCV学习代码记录——轮廓(contour)检测
    OpenCV学习代码记录——canny边缘检测
    基于Android平台的会议室管理系统具体设计说明书
    关系型数据库工作原理-事务管理(一)(翻译自Coding-Geek文章)
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11183475.html
Copyright © 2011-2022 走看看