子程序描述
名称:dtoc
功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
参数:(ax)=word型数据
ds:si指向字符串的首地址
返回:无
应用举例:编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。
在显示时我们调用本次实验中的第一个子程序show-str。
提示
下面我们对这个问题进行一下简单地分析。
(1) 要得到字符串“12666”,就是要得到一列表示该字符的ASCII码:31H、32H、36H、36H、36H。
十进制数码字符对应的ASCII码=十进制数码值+30H
要得到表示十进制数的字符串,先求十进制数每位的值。
例:对于12666,先求得每位的值:1、2、6、6、6。再将这些数分别加上30H,便得到了表示12666的ASCII码串:31H、32H、36H、36H、36H。
(2) 那么,怎样得到每位的值呢?采用除10求余的方法。
用10除12666,共除5次,记下每次的余数,就得到了每位的值。
(3) 综合以上分析,可得出处理过程如下:
用12666除以10,循环5次,记下每次的余数;将每次的余数分别加30H,便得到了表示十进制数的ASCII码串,
(4) 对(3)的质疑:
在已知数据是12666的情况下,知道进行5次循环。可在实际问题中,数据的值是多少
程序员并不知道,也就是说,程序员不能事先确定循环次数。
那么,如何确定数据各位的值已经全部求出了呢?我们可以看出,只要是除到商为0,各位的值就已经全部求出。可以使用jcxz指令来实现相关的功能
代码如下:
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
;在8行3列用绿色显示字符串
mov ax, data
mov ds, ax
call show_str
mov ax, 4c00h
int 21h
;将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
;将用到的寄存器全部入栈
dtoc: push ax
push bx
push cx
push si
push di
mov bx, 10
;将所有得到的余数+30H压入栈中
calc: mov dx, 0
div bx
add dx, 30h
push dx
inc si
mov cx, ax
jcxz ok1
jmp short calc
ok1: mov cx, si
mov di, 0
;循环出栈并放进data数据段
s: pop dx
mov [di], dl ;针对除数为10的特定写法,如果余数在一个字节下无法存放,需要重新处理
inc di
loop s
;弹出所有入栈的寄存器
pop di
pop si
pop cx
pop bx
pop ax
ret
;为了不让子程序干扰主程序中寄存器的值,将所有子程序会用到的寄存器进行压栈
show_str:push ax
push bx
push cx
push dx
push es
push si
push di
mov ax, 0B800h
mov es, ax
;初始化显示字符首地址
mov al, 160;每行占80个字符,共160个字节
mov bl, dh
dec bl
mul bl
mov bx, ax
;偏移量,三列 即从第三个字符(第六个字节)开始显示
mov al, 2
dec dl
mul dl
add bx, ax
mov di, 0
mov al, cl
call change
change: mov cl, [si]
mov ch, 0
jcxz ok
mov ch, al
mov es:[bx + di], cx
inc si
add di, 2
jmp short change
;出栈顺序与进栈顺序相反
ok: pop di
pop si
pop es
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start
运行结果:

本文详细解析了DTOC子程序,介绍了如何将16位数据转换为十进制字符串,并在指定位置用特定颜色显示。文章深入分析了通过除10求余数的方法获取每一位的值,再将其转化为ASCII码,最终形成字符串的过程。

189

被折叠的 条评论
为什么被折叠?



