ROL DX,1是不带进位的循环左移(即数首尾成环左移位),也就是移出的最高位码,进入了空出的最低位中,这里四次ROL DX,1 后,结果是原16位码的最高四位,依次放到了最低4位上,也就是在低8位DL的低4位上,这4位正好是原DX的高4位,所以这样就取得了原DX的高4位。
XOR DX,DX是DX自己异或,有DX清零的作用,在做除法时,32位被除数是高16放在DX中的,低16位放在AX中的,16位除数就放在BX中,试想当只有16位被除数时,是不是整个被除数都放到了AX里了,但计算机做除法运算,被除数总是32位的,那这时我们就需要将被除数的高16位补充零(即扩展被除数高16位,以适应计算机运算需要),所以XOR DX,DX对DX的清零的目的,就是扩展被除,如果不这么做,DX原有的数是会参加除法运算的哦,结果肯定会出错。
只要是字母,无论大写变小写还是小写变大写,下面这条指令是通用的。
xor al,20h ;假设这个字母存于al中。
至于接受键盘输入、显示字符等,请楼主自行编制。若是初学,编不出来,也可代劳。
push ax ; ax 的数据压入堆栈
pop ax ; 出栈 恢复 ax 数据
调用子程序前为了 保存 ax 的数据 不 受到影响,返回时 恢复原来的数据。
如果子程序不用到 ax 则可以 省去上述 *** 作。
补充:之前第一段话说的有问题,所以修改了下,如下:(另外提交的时候没注意,第一个兄弟的回答已经是正确的了^_^)
主要思想是0~9转为对应的ASCII码时加30h,而a,b,c,d,e,f则加37h,比30h多出来的7h就是通过adc(多加了CF的01h)以及daa(多加了06h)实现的。
先说对0~9的,以5为例,
and al,0fh
add al,90h
变为95h
daa
这个时候的daa,由于95h低位,高位都小于9,且无进位,所以不变
adc al,40h
95h + 40h + CF = D5h
daa
低位不变,高位大于9,所以加60h,变为35h,且CF = 1
最终结果为35h,即字符5对应的ascii码53
然后是A~F,以C为例:
and al,0fh
add al,90h
变为9Ch
daa
这个时候的daa,先看低位,由于低位是C,大于9,所以加06h,结果变为A2h,再看高位,高位A,大于9,所以加60h,变为02h,CF = 1(有进位)
adc al,40h
adc *** 作,02h + 40h + CF = 43h
daa
此时43h低高位都小于9,所以无变化。最后结果43h,也即C的ASCII码67
你的两个答案都不正确,正确答案是ADD AL,07H
因为十六进制数数码是0~9、A~F,对应ASCII码为30H~39H、41H~46H。
程序一开始把AL低4位的十六进制数加了30H,然后和39H比较,这里判断十六进制数是属于0~9还是A~F,若是0~9的数,加30H后就是所求的ASCII码了,但是如果是A~F,那么加30H后得到3AH~3FH,这很显然不是A~F的ASCII码,要想得到正确的结果(41H~46H),还要再加07H才行。
写个程序试试吧:
cseg segment
assume cs:cseg
begin: mov al,0ah ;假设带转换的十六进制数是0ah
and al,0fh ;这里可是0FH,不是OFH哦
add al,30h
cmp al,39h
jbe done
add al,7
done: mov dl,al ;调用2号功能显示这个十六进制数的ascii码
mov ah,2
int 21h
mov ah,4ch
int 21h
cseg ends
end begin
对于第1个字符,call htoasc 之后al里面应该是30H(这时候是对的,‘0’的ASCII码正是30H),然后又执行rol al,4,al变成03H了(结果已经错)。
03H不是一个可显示字符,call dispc显示的结果当然不对,你应该把call htoasc 之后的rol al,4这行删掉。
其实代码里面显示低位的时候就没有rol al,4
以上就是关于汇编小问题全部的内容,包括:汇编小问题、用汇编语言masm做 :编一个程序, 把从键盘输入的小写变成大写并显示出来、汇编语言调用子程序前为什么要push ax,之后再pop ax等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)