汇编课程设计一(记录)

assume cs:code,ds:data,es:table,ss:stack

data segment
    ;bx = 0 
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995' 
    ;表示21年的个21个字符串,4*21=84
    ;bx+84
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ;以上表示公司21年的总收入的dword型数据,dx高位,ax低位, 4*21=84
    ; bp+84+84 = bp+168
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635
    dw 8226,11542,14430,15257,17800
    ;以上表示公司员工人数word 共21组数据 2*21=42 
data ends

table segment
    db 21 dup ('year    x          y        z  ',0)
    ;             0    8   19  28
table ends 

stack segment
    db 64 dup (0)
stack ends

code segment

start:    
    ;设置栈顶,
    mov ax,stack
    mov ss,ax
    mov sp,64 
    ;设置es指向原始数据data bx为db偏移,bx+84为dd偏移,bp为dw偏移
    mov ax,data
    mov es,ax
    mov bx,0
    mov bp,168
    ;设置ds:si指向字符串table数据的首地址
    mov ax,table 
    mov ds,ax
    mov si,0            
    mov cx,21 ;循环次数
    loop_s:
            ;复制年份数据到ds:si中,ds:0
        mov ax,es:[bx]
        mov [si],ax 
        mov ax,es:[bx+2]
        mov [si+2],ax         ;加2是因为ax是16位,16/8=2         
            ;复制总收入数据,转换成字符串
        mov ax,es:[bx+84]
        mov dx,es:[bx+86]    
        push si
        add si,8
        call dtoc
        pop si                 ;将ds:si重新指向每一行的行首
            ;复制员工数据,转换成字符串
        mov ax,es:[bp]
        mov dx,0    ;因为员工数小于16位,所以高16位置0
        push si
        add si,19
        call dtoc
        pop si     
            ;计算平均数,结果在ax中
        mov ax,es:[bx+84]
        mov dx,es:[bx+86]        
        div word ptr es:[bp]    
        
        mov dx,0  ;因为平均数小于16位,所以高16位置0
        push si 
        add si,28
        call dtoc 
        pop si     
            ;计算行数,一共循环21次,每次都会加4,加2,加32 ,
        mov ax,bx
        push bx 
        push cx 
        mov bl,4
        div bl        ;所以除以每一次加的数得到行数,
        mov dh,al    ;结果在al中,传送到dh中
        add dh,1     ;行数加1,因为会向上移一行
        mov dl,5    ;在第几列开始
        mov cl,2
        call show_str 
        pop cx
        pop bx
        ;pop cx 多出栈一个cx,程序进入死循环
        add bp,2
        add bx,4
        add si,32        
    loop loop_s        
            
    mov ax,4c00h
    int 21h
        
;\+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
;|名称:dtoc                                                     |
;|功能:将dword型数据转变为表示十进制的字符,字符串以0为结尾符.|
;|参数:(ax)=dword型数据的低16位 (dx)=dword型数据的高16位        |
;|        ds:si指向字符串首地址                                       |
;|返回:无                                                             |
;/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\

dtoc:
  ;入栈-----------------------
    push bx 
    push cx
    push di 
    push ax
    push dx
    push si 
  ;---------------------------
    mov di,0
  dtoc_div:
    mov cx,10
    call divdw
    add cx,30h
    push cx 
    inc di
    mov cx,dx 
    add cx,ax 
    jcxz dtoc_div_end     
    jmp short dtoc_div
 dtoc_div_end:
    mov cx,di
 dtoc_mov:
    pop ax 
    ;mov [si],ax 此处传送两个字的进入一个字符中,所以出错
    mov [si],al 
    inc si 
    loop dtoc_mov    
  ;出栈-----------------------
    pop si 
    pop dx 
    pop ax 
    pop di 
    pop cx 
    pop bx 
  ;---------------------------      
    ret

;\+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
;|名称:divdw                                                    |
;|功能:解决除法运算时,可能出现的数据溢出问题                   |
;|参数:被除数:ax+dx 32位组合   除数:cx                        |
;|返回:商:ax+dx    余数:cx                                       |
;|X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N                             |
;|X被除数,N除数,int取整,rem取余,H高16位,L低16位,*65536存在dx中 |
;/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\

divdw:
    jcxz div_ok ;如果cx是0则跳到div_ok处
  ;入栈-----------------------
    push bx 
  ;---------------------------        
    push ax     ;把低位暂存在栈中
    mov ax,dx  
    mov dx,0
    div cx        ;商ax=int(H/N)*65536 余dx=rem(H/N)*65536    
    mov bx,ax    ;把高位的商暂存在reg中    
    pop ax    
    div cx        ;[rem(H/N)*65536+L]/N    
    ;商ax 余dx
    mov cx,dx  ;将结果余数放入cx中
    mov dx,bx  ;把暂存在reg中的商放入高位 int(H/N)*65536
  ;出栈-----------------------
    pop bx 
  ;---------------------------    
div_ok:    
    ret        

;\+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
;|名称:show_str                                                 |
;|功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串.     |
;|参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),        |
;|      (cl)=颜色,ds:si指向字符串首地址                         |
;|返回:无                                                           |
;/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\

show_str:
    ;入栈-----------------------
        push ax
        push es
        push bx
        push si 
    ;---------------------------    
        ;设置显示缓冲区
        mov ax,0B800h
        mov es,ax
        ;8位乘法,al与另一个reg相乘,结果在ax中
        mov al,160            ;行的倍数, 
        mul dh                
        mov bx,ax
        mov al,2             ;列的倍数
        mul dl 
        add bx,ax             ;用bx做偏移地址
        mov ah,cl           ;颜色存放在ah,字符存放在al
        mov ch,0
    show_xh:
        mov cl,[si]
        jcxz show_xh_ok           ;如果cx是0则跳到show_xh_ok处
        mov al,cl                ;cx非0,al=cl=[si]
        mov word ptr es:[bx],ax    ;此时,高位ah=颜色,低位al=字符
        inc si
        add bx,2
        ;loop show_xh
        jmp short show_xh
    show_xh_ok:                        
    ;出栈-----------------------
        pop si
        pop bx
        pop es
        pop ax
    ;---------------------------            
    ;释放show_str子程序
    ret
        
code ends

end start

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值