对于机器来说,它是看不懂我们认为定义的数字的,必须要先转换为人与机器的转换协议,就是ASCII码,所以需要先转换再显示
这里将用到之前两节中用到的子函数
代码如下:
assume cs:code, ds:data
data segment
db 10 dup(0)
dd 197514
data ends
code segment
start:mov bx, data
mov ds, bx
mov ax, ds:[10]
mov dx, ds:[12]
mov si, 0
call dtoc
mov dh, 8
mov dl, 3
mov cl, 2
call show_str
mov ax, 4C00H
int 21H
dtoc:push sp
push ds
push es
push bx
push cx
push bp
push si
push di
push dx
push ax
mov bp, sp ;[bp]是ax, [bp+2]是dx
mov di, 0
mov bx, [bp] ;将要显示的数值的低位取出
mov si, [bp + 2] ;将要显示的数值的高位取出
s1:mov ax, bx ;调用之前写的子函数防止溢出问题
mov dx, si ;这里的ax和dx分别存放数据的低位和高位
mov cx, 10 ;cx存放除数
call divdw
add cl, 30H ;处理后cx得到余数
mov ch, 0
push cx ;在该循环中,push操作只进行了两次,因为当余数为最后一个的时候,商已经变为零
add di, 1 ;如果是两位数,di加了两次
mov bx, ax ;将得到的商的低位送入bx,进行循环
mov si, dx ;将得到的商的高位送入si,进行循环
mov cx, ax ;ax中存放的是商的低位, 当商的低位为零时结束循环
jcxz ok1
jmp s1
ok1:mov si, 0
mov cx, di
s2:pop bx ;出栈两次
mov ds:[si], bl
add si, 1 ;;;;;;;;;;;;;;;;;;;;;;;
loop s2
mov bl, 0H
mov ds:[si], bl
pop ax
pop dx
pop di
pop si
pop bp
pop cx
pop bx
pop es
pop ds
pop sp
ret
show_str:push ax
push cx
push si
push di
push bx
push es
push dx ;用栈将行数和列数保存起来
mov bp, sp
mov al, [bp + 1]
mov ah, 0
mov bx, 160
mul bx
mov si, ax ;做了16位乘法算法后,dx的值已经被改变
;si中存放显示区域的每行的首偏移地址
mov al, [bp] ;因为每个字符是用由两个字节组成的,所以这里计算列数
mov bl, 2
mul bl
mov bx, ax ;bx中存放每个字符的第一个字节的地址
pop dx ;将上次入栈的dx出栈
mov di, 0
mov dl, cl ;将颜色信息给dl
mov ax, 0B800H
mov es, ax
s:mov cl, ds:[di]
mov ch, 0
jcxz ok
mov es:[si + bx], cl
mov es:[si + bx + 1], dl
add bx, 2
add di, 1
jmp s
ok:pop es
pop bx
pop di
pop si
pop cx
pop ax
ret
divdw:push si
push di
push ax
push dx
push cx
mov bp, sp ;[bp]是cx,[bp+2]是dx,[bp+4]是ax
mov ax, [bp + 2] ;ax存放16位除法的低位
mov dx, 0
mov bx, [bp]
div bx
mov si, ax ;si存放商
mov ax, [bp + 4]
mov bx, [bp]
div bx
mov cx, dx
mov dx, si
pop di
pop di
pop di
pop di
pop si
ret
code ends
end start
这里同样用的是子函数的形式给出来的,主要的语句已经解释了,需要学习者仔细看注释,毕竟是汇编语言,需要理解的部分很多,下面是运行结果:
程序中输入的参数是197514,所以输出是: