《汇编语言 edition 3》课程设计一我的是实现版本

328 阅读5分钟

实现思路是先按照书中引导的3个问题写好子程序,然后再写,本课程设计的部分。由于是低级语言建议多写注释,(我的代码中加了许多)。多多的debug调试。

assume cs:codesg

data segment
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995';年
    ;收入
    dd 16,22,382,1536,2390,8000,16000,24486,50065,97479,140417,197514
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800;人数
data ends

table segment
    db 21 dup ('year s       n     ?   ',0)
table ends

stack segment
    db 16 dup (0)
stack ends

codesg segment
start:
    mov ax,table
    mov ds,ax;表
    
    mov ax,stack
    mov ss,ax
    mov sp,10H
    
    mov ax,data
    mov es,ax;es data
    
    mov cx,21;循环21次
    mov bx,0
    mov bp,0
    mov di,0
    
 ;name s
 ;数据格式化存入内存中('year s       n     ?   ',0)| bits (4 7 5 3 ) + '0'
 ;每行共24字符   
 s: 
   mov si,0
   push cx
   mov cx,4;年有四位
   
   s0: ;年
      mov al,es:[bp+si+0]
      mov byte ptr [bx].0h[si],al
      inc si
      loop s0
   
   ;收入 原:逐个字节copy
   ;    现:改为对应数值各个位的ASCII码(用于显示)
    
    push ax
    push dx
    mov si,0
    mov ax,es:es:84[bp+si];dword 低16位 84 = 4*21
    add si,2
    mov dx,es:84[bp+si];dword 高16位
    mov si,bx
    add si,5;该行收入对应的位置
    call dtoc;数字转成字符串存到内存
    pop dx
    pop ax
 
    ;人数
    push ax
    push dx
    mov ax,es:[168+di];168十进制数 4*21 + 4*21 人数的起始地址
    mov dx,0
    mov si,bx
    add si,0dh;表中人数对应的位置
    call dtoc
    pop dx
    pop ax
    
    ;mov word ptr [bx].0aH,ax
    
    ;div 算平均工资 (16位除法 dx=高16位 ax=低16位 || 结果ax=商 dx=余数)
    ;目前没有将测量数值转换成平均值
    mov dx,es:es:84[bp+2];dword 低16位 84 = 4*21
    mov ax,es:es:84[bp+0];dword 低16位 84 = 4*21
    div word ptr es:168[di];求得商ax
    
    ;下边4行摆放商到合适的位置
    mov dx,0
    mov si,bx
    add si,19;表中人均收入对应的位置
    call dtoc
    
    add bx,24;写入新地址 格式化后每行有24个字符(新添加0字符)
    add bp,4
    add di,2
    
    pop cx
    loop s
    
    mov cx,21
    mov dh,2;行
    mov si,0;从 ds:[0]开始显示
  show:
    push si
    push cx
    ;显示表格
    ;显示配置项
    
    mov dl,3;列
    mov cl,2;绿色
    
    call show_str;显示
    add si,13
    add dl,13
    
    call show_str
    add si,6
    add dl,6
    
    call show_str
    
    pop cx
    pop si
    add si,24
    inc dh
    loop show
    
    mov ax,4c00h
    int 21h
    
    ;进行不会产生溢出的除法运算
;被除数位dword dx 高 16位 | ax低16位
;cx 除数
;结果 dx 高16位 | ax 低16位 | cx余数
 divdw:
       push si
       mov si,ax;低16位
       mov ax,dx
       mov dx,0h

       div cx;ax 商 dx余数
       push ax
       
       mov ax,si
       div cx;
       
       mov cx,dx;存余数
       pop dx
       pop si
       
       ret 
 ; 输入 (ax)=dword型数据的低16位
 ;     (dx)=dword型数据的高16位
 ;结果  ds:si指向字符串的首地址      
 dtoc:
       push di;余数个数
       push dx
       push cx
       push si
       push bx
       mov di,0
       mov cx,10
       
       push ax
       push dx 
    ;s0 求余数个数
    ;输入 除数 cx 16位  操作数低16位 ax 操作数 高16位dx
    ;单步结果 商ax 余数dx
    ;最终结果 di 存储余数个数
     dtocs0: 
        push cx
        call divdw
        mov cx,dx  
        or cx,ax;商为0代表数字处理结束
        inc di
        jcxz dtocs;通过把商转移进cx(dx or ax) 判断除法是否结束
        pop cx
        jmp dtocs0
      dtocs:
        pop cx
        push bx;push
        mov bx,si
        mov byte ptr ds:[di+bx],0;字符串结束符 ds:[si]指向生成字符串的首地址
        pop bx;pop
        pop dx
        pop ax; dx:ax源操作数
     ;s1 把数字的ASCII存到ds:0中
     dtocs1:  
        push cx ;除数
        dec di
        call divdw
        add cl,30h
        push bx
        mov bx,si
        mov ds:[di+bx],cl;位值对应的ASCII码
        pop bx
        mov cx,dx;!!!
        or cx,ax;!!! 判断商为0
        jcxz dtocok
        pop cx
        jmp dtocs1
    dtocok:
        pop cx
        pop bx
        pop si
        pop cx
        pop dx
        pop di
        ret
    
    show_str:
        push cx
        push ax
        push di
        push si
        push bx
        push dx
        
        mov al,0a0h;每行字符数
        sub dh,1
        mul dh
        mov di,ax;//行数*行
        mov dh,0
        sub dl,1
        mov al,2h
        mul dl
        add di,ax
        
        mov ax,0b800h
        mov es,ax
        mov bl,cl;样式
 
    ;起始地址 ds:[si]  ,显示该字符串
    ;样式位于bl中         
    shostrs:   
        mov cl,[si]
        mov ch,0h
        jcxz showstrok
        mov byte ptr es:[di],cl
        inc di
        mov byte ptr es:[di],bl
        inc di
        inc si
        jmp shostrs
    
 showstrok: 
        pop dx
        pop bx
        pop si
        pop di
        pop ax
        pop cx
        ret
    
codesg ends

end start