|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- ;名称:dtoc
- ;功能:将word型数据转变为表示十进制数的字符串, 字符串以0为结尾符
- ;参数:(a x) =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 dx
- push cx
-
- ;计算字符总数
- mov bx,1 ;bx保存字符总数
- mov dl,10
- push ax ;保存被除数
- s2:div dl
- mov ch,0
- mov cl,al ;把商传给cx
- jcxz ss1
- inc bx ;字符数加1
- mov ah,0 ;清除余数,ax就是商
-
- mov cx,2 ;保证loop时,cx不等于0
- loop s2
-
- ss1:pop ax ;读取被除数
-
- ;写入字符
- ;bx=字符总数,bx-1就是偏移量
-
- mov bx,0 ;写结束字符0
-
- s3:div dl
- add ah,30h ;把余数转换成ASCII吗
- mov [bx-1],ah ;写入字符,注意倒序
- mov ah,0 ;清除余数,ax就是商
- mov ch,0
- mov cl,al ;把商传给cx
- jcxz s4 ;如果商=0就结束
- dec bx
- mov cx,2 ;保证loop时,cx不等于0
- loop s3
-
- s4: mov si,0 ;字符串首地址
- pop cx
- pop dx
- pop bx
- ret
-
-
-
-
- show_str: ;子程序用到的寄存器一定要先保存
- push ax
- push es
- push bx
- push bp
-
-
-
- mov ax,0B800h ;显存段地址
- mov es,ax
- mov bl,cl ;bl保存颜色
-
- ;计算偏移量
- mov al,160
- mul dh
- mov bp,ax
- mov al,2
- mul dl
- add bp,ax ;计算出偏移量;bp显存偏移量
-
- s:mov ch,0
- mov cl,[si] ; 提取字符
- jcxz s1 ;0字符返回
- mov es:[bp],cl
- mov es:[bp+1],bl
- inc si
- add bp,2
- jmp s
-
-
-
- s1:pop bp
- pop bx
- pop es
- pop ax
- ret ;返回
-
- code ends
- end start
-
-
-
复制代码
我的问题:
调试执行时 发现执行div dl 之后,出现错误,如图
根据代码分析,执行 div dl 之前, dx 寄存器的值应该是被除数 ax 的高16位,而被除数 ax 的低16位应该是 al 寄存器的值。在这段代码中, ax 寄存器的值是 12666 ,所以 dx 的值应该是 0 , ax 的值应该是 12666 。但是在执行 div dl 之前,代码没有将 ax 的值保存到 dx 寄存器中,导致 dx 的值不正确,从而引发错误。
为了解决这个问题,可以在执行 div dl 之前,添加一条指令 mov dx, ax ,将 ax 寄存器的值保存到 dx 寄存器中。这样就可以确保 dx 的值正确,从而避免错误的发生。
修改后的代码如下:
- dtoc:
- push bx
- push dx
- push cx
-
- ; 计算字符总数
- mov bx, 1 ; bx 保存字符总数
- mov dl, 10
- push ax ; 保存被除数
- s2:
- mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
- div dl
- mov ch, 0
- mov cl, al ; 把商传给 cx
- jcxz ss1
- inc bx ; 字符数加1
- mov ah, 0 ; 清除余数,ax 就是商
-
- mov cx, 2 ; 保证 loop 时,cx 不等于 0
- loop s2
-
- ss1:
- pop ax ; 读取被除数
-
- ; 写入字符
- ; bx = 字符总数,bx - 1 就是偏移量
-
- mov bx, 0 ; 写结束字符 0
-
- s3:
- mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
- div dl
- add ah, 30h ; 把余数转换成 ASCII 码
- mov [bx-1], ah ; 写入字符,注意倒序
-
- mov ah, 0 ; 清除余数,ax 就是商
- mov ch, 0
- mov cl, al ; 把商传给 cx
- jcxz s4 ; 如果商 = 0 就结束
- dec bx
- mov cx, 2 ; 保证 loop 时,cx 不等于 0
- loop s3
-
- s4:
- mov si, 0 ; 字符串首地址
-
- pop cx
- pop dx
- pop bx
- ret
复制代码
修改后的代码中,添加了 mov dx, ax 指令,将 ax 寄存器的值保存到 dx 寄存器中,确保了 dx 的值正确。这样就可以正常执行 div dl 指令了。
|
-
|