X32汇编AAA,AAS,AAM,AAD,DAS,DAA

今天看了下IA-32架构手册卷二关于十进制算术指令的相关部分,现在做一下总结:

先解释以下几个概念:

1. ASCII码十进制数: 就是十进制ASCII码的十六进制表达形式。 比如说,十进制中的数字1。在十六进制的表示就是31h。

这也就是ASCII码十进制数,即在显示的时候是十进制的。

2.非压缩型BCD码: 举例: (AL) = 03h,那么代表的就是未压缩的十进制数字3。特点是高4位必定是0,低4位取值范围是0-9。 直白的说就是用两个十六进制数字组在一起也就是16位二进制数,高4位必定为0,低4位是二进制的0-9以此来表示十进制中的0-9。

3.压缩型BCD码: 每四位表示一个十进制数字,一个字节有8位所以一个字节可以表达两个十进制数字。比如说82这个十进制数字如果用压缩型BCD码表示就是10000010。非压缩型表示是00001000 00000010。

----------------------------------------------------------------------------------------------------------------------------------

AAA指令(ASCII adjust after addition):


翻译:

调整两个非压缩BCD码值来变成一个非压缩BCD码的结果。这个指令中AL寄存器是暗藏的源操作数和目的操作数。AAA指令只有跟在ADD指令后面才有效。(用add加两个非压缩BCD码值并把结果存储在AL寄存器中),AAA指令接着便调整AL寄存器中的内容使其变成一位正确的非压缩BCD结果

如果add指令产生了十进制进位,AH寄存器加1并且CF和AF标志位置位。如果没有十进制进位,CF和AF标志清除并且AH寄存器不变。AL的4~7位(即高四位设为0)

下面那段伪码的含义就是上面那些话,只要看else部分就行

如果 (AL的低四位大于9) 或者 (辅助进位标志位是1) 那么AX就加上106h,也就相当于AH加1,AL的低四位加6,并且CF,AF设0

不然 AF = 0, CF = 0

举例:

mov ah, 0 ;先把ax高位清空
mov al, '8' ;ax = 0038h
add al, '2' ;ax = 006Ah 即38h + 32h = 6Ah
aaa ;调整成一个非压缩BCD码 变成0100h 
or ax, 3030h 0100h 和3030h按位or操作成3130h

解释: 这里用两个ASCII十进制数(非压缩)相加后变成了一个ASCII码十进制数。然后AAA指令就把AX中的值转化成了两个非压缩的BCD码

AAD指令(ASCII adjust before division):


翻译:

调整两个非压缩BCD数字(最低有效数位在AL寄存器,最高有效数位在AH寄存器)以使一个除法操作产生的结果将生成一个正确的非压缩BCD码值。AAD指令只有在它在一个DIV指令之前才有效,这个除法指令用了在AX寄存器中由非压缩BCD码通过AAD指令调整好的值。

AAD指令设置AL寄存器为(AL + (10 * AH)),接着清除AH寄存器至00H。然后AX寄存器中的值就等于在AH和AL中的原始的非压缩两位数字(十进制)的等价物。
AAD指令的广义版本允许调整两个任意进制的非压缩数字,通过设置8位立即数来选择进制(例如,08h是八进制,0Ah是十进制或者0Ch是十二进制)。ADD助记符被所有编译器翻译成用来把未压缩BCD码调整成ASCII(十进制)值。为了调整数值成另外的进制,指令必须被手工编码成机器码。

这个指令在兼容模式和传统模式下按照描述的执行。它在64位模式中无效.

伪代码:

把AL复制一份到tempAL,把AH复制一份到tempAH,AL = (tempAL + (tempAH * 0Ah))注意这里计算出来是10进制

最后AH = 0 

举例:

mov ax, 0307h
aad ;al = (3 * 10 + 7) ah = 0 ax=37=25h
mov bl, 5
div bl

解释:

这里实际上就是把非压缩的BCD码转化成为ASCII十进制数字,方便后面的除法操作符运算。而上面说的AAA指令是把ASCII十进制数字转变成非压缩BCD码

AAM指令(ASCII adjust after multiplication)


翻译:

调整两个非压缩BCD值(即ASCII码十进制值)的乘积来创造一对非压缩(十进制)BCD码值。对于这个指令来说AX寄存器是暗藏的源操作数和目的操作数。AAM指令只有它跟在一个MUL指令后面才有效(MUL指令用来乘两个非压缩BCD码值并储存一个字长度的结果到AX寄存器)。AAM指令接着调整AX寄存器的内容包括了两位正确的非压缩BCD码结果。
这个指令的广义版本允许调整AX寄存器的内容来创造两位非压缩任意进制的数字。这里,八位立即数被设定成选中的进制(内容同上)。AAM助记被所有汇编器翻译成调整ASCII(十进制)值。为了调整成其他进制,指令必须被手工编码成机器码
这个指令在兼容模式和传统模式下按照描述的执行。但在64位模式下无效

伪代码:

把AL的内容复制一份到tempAL,把tempAL / 0Ah 然后赋值给AH,最后把tempAL % 0Ah的值赋值给AL

举例:

mov bl, 05h
mov al, 06h
mul bl ;ax = 001Eh
aam ; ah = tempAL / 0Ah = 03h al = tempAL % 0Ah = 00h ax = 0300h
解释:

把两个非压缩的BCD码的乘积变成非压缩BCD码

AAS指令(ASCII adjust after subtraction)


翻译:

调整两个非压缩BCD码值的相减的结果来创造一个非压缩的BCD结果。AL寄存器是这个指令暗藏的源操作数和目标操作数。AAS指令只有当它跟在一个SUB指令后面才有用(两个非压缩BCD码相减并且把结果存在一个字节的AL寄存器中)。AAS指令接着调整AL寄存器中的内容包含一位非压缩的BCD码结果
如果减法生成了一个十进制进位,AH寄存器减1,并且CF和AF标志位置位。如果没有那么CF和AF标志位清除并且AH寄存器不改变。无论哪种情况,AL寄存器都要把它高四位清除。

伪代码:

条件和AAA相同就是结果加的变成减罢了

例子:

mov ah, 0
mov al, '8' 
sub al, '9' ;al = 0FFh
aas ;AF = 1 -> 0FF09h

解释:

和AAA相反

DAS指令(decimal adjust after subtraction)


翻译:

调整两个压缩的BCD码值相减的结果来创造一个压缩的BCD码结果。AL寄存器是暗藏的源操作数和目的操作数。DAS指令只有跟在SUB指令后面时才有效(减去一个2位压缩BCD码值并且在AL寄存器内存储一个8位结果)。DAS指令调整AL寄存器的内容来包含一个正确的2位压缩BCD码结果。如果一个十进制借位被侦测到,CF和AF标志位也会相应地被置位。
这个指令在兼容模式和传统模式的执行如上所述。在64位模式是无效的。

伪代码:

不解释了,与DAA相反

例子:

mov bl, 48h
mov al, 85h
sub al, bl 
das

解释:

如上

(完)






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值