题目
例5.1 试编制一个程序把BX寄存器中的二进制数用十六进制数的形式在屏幕上显示出来。
思路
想要将BX中的值一位一位的显示,我们首先想到利用循环移位,然后取出每一位的数并转化为字符串进行显示。
要如何移位呢?通过循环右移4位把最高字节的数移到最低位,然后与0fh相与,取出该位。设置cx计数器为4,移位4次就可以将BX中的数全部取出,这里涉及到了循环。
要如何将每一位的数转化为ASCII码呢,可以看到0-9的ASCII码对应的是30H-39H,而A-F的ASCII码对应的是41H-46H。这必然要用分支来实现,首先需要判断该位是属于哪一个分支的,然后再进行相对应的操作。为了简化程序,我们先加个30H,如果是数字就直接输出,如果不是数字则再加上07h转化为字母。
流程图如下:
代码
datasg segment
datasg ends
codesg segment
assume cs:codesg,ds:datasg,es:datasg
main proc far
start:
push ds
xor ax,ax
push ax
mov ax,datasg
mov ds,ax
mov es,ax
mov bx,123AH
mov ch,4 ;ch用于循环移位
rotate: ;这里使用到了循环
mov cl,4 ;cl用于每次移4位,rol的操作数不能是立即数
rol bx,cl ;循环右移4位
mov ax,bx
and al,0fh ;取低四位
add al,30H ;’0’-’9’ ASCII 30H-39H 转化为
cmp al,3aH ;比3a小的是数字,则直接跳转输出
jb printf ;这里使用到了分支
add al,07h ;否则再加上07h ’A’-’F’ ASCII 41H-46H
printf:
mov dl,al
mov ah,2 ;调用2号中断输出字符串
int 21h
dec ch ;ch-1
jnz rotate ;如果ch不等于0,继续循环
ret
main endp
codesg ends
end start
调试过程
反汇编
接着go到初始化后的部分,查看第一次循环各个寄存器变化的情况
可以看到,发生了跳转
已经输出了正确的结果
跳到输出字母A的循环当中来,检验字母输出的正确性
没有发生跳转
输出结果正确
g到底,结束调试,程序正确