汇编语言 王爽 实验10 编写子程序

在本次实验中,通过编写3个子程序来认识几个常见的问题和掌握解决这些问题的方法。

1. 显示字符串

问题
编写一个通用的显示字符串的子程序,提供显示的位置(行、列)、内容和颜色的接口。
应用举例:在屏幕的8行3列,用绿色显示data段中的字符串。

assume cs:code

data segment
    db 'Welcome to masm!',0
data ends

code segment
    
    start:
    mov dh,8            
    mov dl,2
    mov cl,2
    mov ax,data
    mov ds,ax
    mov si,0
    call show_str
    
    mov ax,4c00h
    int 21h
    
    ;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
    ;参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),
    ;      (cl)=颜色,ds:si指向字符串的首地址
    ;返回:无
    show_str: 
    push ax
    push bx
    push cx
    push di
    
    mov ax,0b800h           ;使es指向显示缓冲区的起始段地址
    mov es,ax
    
    sub ax,ax               ;使di指向指定列
    mov al,2
    mul dl
    mov di,ax
    
    mov al,0a0h             ;使bx指向指定行
    mul dh
    mov bx,ax
    
    mov dl,cl
    sub cx,cx
    
    show_str_change:
    mov cl,ds:[si]
    jcxz show_str_ok        
    mov es:[bx+di],cl       
    mov es:[bx+di+1],dl          
    inc si
    add di,2  
    jmp show_str_change

    show_str_ok: 
    pop di
    pop cx
    pop bx
    pop ax
    ret

code ends

end start

2. 解决除法溢出的问题

问题
使用div指令做除法运算时,如果结果的商大于al或ax所能存储的最大值,将会发生除法溢出错误。编写一个名为divdw的子程序来解决该问题。
子程序描述

名称:divdw
功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
参数:(ax)=dword型数据的低16位
     (dx)=dword型数据的高16位
     (cx)=除数
返回:(dx)=结果的高16位,(ax)=结果的低16位
     (cx)=余数

应用举例:计算1000000/10(F4240H/0AH)

assume cs:code

code segment
    
    start:
    mov ax,4240h
    mov dx,0fh
    mov cx,0ah
    call divdw
    
    mov ax,4c00h
    int 21h
    
    ;参数:(ax)=dword型数据的低16位
    ;      (dx)=dword型数据的高16位
    ;      (cx)=除数
    ;返回:(dx)=结果的高16位,(ax)=结果的低16位
    ;      (cx)=余数
    divdw:
    push bx
    
    push ax         
    mov ax,dx
    mov dx,0
    div cx
    mov bx,ax
    
    pop ax
    div cx
    mov cx,dx
    mov dx,bx
    
    pop bx
    ret
    
code ends

end start

3. 数值显示

问题
编程,将data段中的数据以十进制的形式显示出来。
子程序描述

名称:dtoc
功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
参数:(ax)=word型数据
     ds:si指向字符串的首地址
返回:无 

应用举例
编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。在显示时调用本次实验中的第一个子程序show_str。

assume cs:code

data segment
    db 10 dup (0)
data ends

code segment
    
    start:
    mov ax,12666  
    mov bx,data
    mov ds,bx
    mov si,0
    call dtoc
    
    mov dh,8
    mov dl,3
    mov cl,2
    call show_str
    
    mov ax,4c00h
    int 21h
    
    dtoc:
    push bx
    push cx
    push si
    
    mov di,0            ;记录字串的长度
    mov cx,0
    dtoc_change:
    mov bx,10
    div bx
    push dx
    inc di    
    mov cx,ax
    jcxz dtoc_write
    mov dx,0
    jmp dtoc_change
    
    dtoc_write:
    mov cx,di
    dtoc_write_s0:
    pop ax
    add ax,30h
    mov ds:[si],ax
    inc si
    loop dtoc_write_s0
    
    dtoc_end:
    pop si
    pop cx
    pop bx
    ret
    
    
    show_str: 
    push ax
    push bx
    push cx
    push di
    
    mov ax,0b800h           ;使es指向显示缓冲区的起始段地址
    mov es,ax
    
    sub ax,ax               ;使di指向指定列
    mov al,2
    mul dl
    mov di,ax
    
    mov al,0a0h             ;使bx指向指定行
    mul dh
    mov bx,ax
    
    mov dl,cl
    sub cx,cx
    
    show_str_change:
    mov cl,ds:[si]
    jcxz show_str_ok        
    mov es:[bx+di],cl       
    mov es:[bx+di+1],dl          
    inc si
    add di,2  
    jmp show_str_change

    show_str_ok: 
    pop di
    pop cx
    pop bx
    pop ax
    ret 
      
code ends

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值