您的位置:首页 > 其它

asm基础——汇编指令之ascii调整指令

2016-03-11 17:47 375 查看
汇编中存在4个指令,用来处理加减乘除之后的ASCII调整,分别是AAA,AAS,AAM和AAD。

所谓的ASCII调整,实际上就是对'0'到‘9'这10个ASCII字符表示的十进制做四则运算之后的一个调整。

因为对于汇编,无法识别特定的ASCII数字,比如说对于’1',在汇编中只能看到0x31这个数字,而没有'1'这样的概念,这会产生一个问题,比如要在显示器上显示1,如果使用汇编,需要改成0x31(即ASCII的'1')再输出,对于单个输出,这样没有问题。但是如果碰到各种运算的话,就会显得麻烦,所以才有了上述的指令,经过转换后,再加上0x30,就得到对应的ASCII值了。

下面是没有使用ASCII调整的一个加法操作:

main PROC
mov eax, '5'
mov ebx, '1'
add eax, ebx
call DumpRegs	; eax显示0x66
exit
main ENDP
END main


此时我们实际需要的结果是0x6(加上0x30后就变成'6'了),因此就可以加上aaa这个命令来做调整。

顺便说一下,aaa表示adjust after addition,加法后调整,这样有助于记忆。

main PROC
mov eax, '5'
mov ebx, '1'
add eax, ebx
aaa		; 加法后的ASCII调整
call DumpRegs	; eax显示0x6
exit
main ENDP
END main

需要注意的是,aaa后,eax的值并不是变成0x36,对于想要输出'6',这个调整还是需要自己加的

还需要注意的是,这里的aaa调整的是eax中的结果,包括aas,aam,aad,它们调整的都只能是eax(对于32位是eax,当然也可以是ax,这里通用eax表示)中的结果

另外,ASCII调整指令还可以处理ASCII十进制的进位操作,修改上面代码中的数值:

main PROC
clc		; 为了方便观察先清楚CF的值,即CF=0
mov eax, '5'
mov ebx, '9'
add eax, ebx
aaa		; 加法后的ASCII调整
call DumpRegs	; eax显示0x6
exit
main ENDP
END main

运行的结果如下:



CF=1表示确实进位了。

另外这里的EAX=0x0104,如果or eax, 3030h,就可以得到ASCII的”14“了,它就是计算的结果。

AAS表示adjust after subtraction。它与AAA的用法相似。

而ASCII乘除调整和ASCII加减调整不同,ASCII加减调整对ASCII十进制加减有效,但是ASCII乘除调整对ASCII十进制乘除并没有效果,它只对未压缩十进制有效。

下面是ASCII十进制和未压缩十进制的区别,对于一个十进制数1234,

它的ASCII十进制表示是31 32 33 34

而对未压缩十进制表示是01 02 03 04

上面例子中的EAX=0x0104就可以看成是14的未压缩十进制表示。

下面是ASCII乘法调整的一个例子:

main PROC
clc		; 为了方便观察先清楚CF的值,即CF=0
mov eax, 5h
mov ebx, 6h
mul ebx
call DumpRegs	; eax显示0x1E,表示十进制的30
exit
main ENDP
END main

上面的例子是在没有使用ASCII调整情况下的结果,下面是使用aam之后的结果:

main PROC
clc		; 为了方便观察先清楚CF的值,即CF=0
mov eax, 5h
mov ebx, 6h
mul ebx
aam
call DumpRegs	;eax显示0x0300
exit
main ENDP
END main

eax的结果是0x0300,表示的是未压缩十进制表示的30。

对于ASCII除法调整,它是在运算之前,对放在eax中的值进行调整:

main PROC
mov edx, 0h	;32位除法需要用到edx,将它清空
mov eax, 0300h	;表示30
aad		;调整后就是0x1E,,因此整个被除数是30
mov ebx, 5
div ebx
call DumpRegs	;eax显示0x6
exit
main ENDP
END main


(写得有点乱,越到后面越不知道这些指令的用处了......)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: