emi*_*lxp 6 x86 assembly decimal instructions bcd
我一直在努力理解来自x86汇编语言的ASCII调整指令.
我看到整个互联网信息告诉我不同的事情,但我想这是以不同形式解释的同样的东西,我仍然没有得到.
谁能解释为什么在AAA的伪代码中,AAS我们必须添加,从AL中的低阶半字节中减去6?
并且有人可以在英特尔指令集手册中解释AAM,AAD和Decimal调整指令伪代码,他们为什么这样,他们背后的逻辑是什么?
最后,有人可以举例说明这些说明是否有用,或者至少在过去它们有用的应用程序中.
我知道现在没有使用这些说明,但我仍然想知道这些说明是如何工作的,这很好.
为什么在AAA的伪代码中,AAS我们必须添加,从AL中的低阶半字节中减去6
因为在十六进制中,每个字符有16个不同的值,而BCD只有10个.当你用十进制数学时,如果数字大于10,你需要取模数10并进入下一行.类似地,在BCD数学中,当加法的结果大于9时,添加6以跳过剩余的6个"无效"值并进入下一个数字.相反,你在减法中减去6.
例如:27 + 36
27: 0010 0111
+ 36: 0011 0110
???????????????
5_13: 0101 1101 (13 >= 10)
+ 6: 0110
???????????????
63: 0110 0011 (13 + 6 = 19 = 0x13, where 0x3 is the units digit and 0x10 is the carry)
Run Code Online (Sandbox Code Playgroud)
执行解压缩添加是相同的,除了您直接从单位数字到十位数,丢弃每个字节的顶部半字节
有关更多信息,请阅读
并且有人可以在英特尔指令集手册中解释AAM,AAD和Decimal调整指令伪代码,他们为什么这样,他们背后的逻辑是什么?
AAM只是从二进制到BCD的转换.你通常以二进制形式进行乘法,然后调用AAM将结果除以10,并将商 - 余数对存储在两个未压缩的BCD字符中
例如:
13*6 = 78 = 0100 1110
78/10 = 7 remains 8 => result = 0x78
Run Code Online (Sandbox Code Playgroud)
AAD是相反的:在除法之前,你调用AAD将它从BCD转换为二进制,并像其他二进制除法一样进行除法
例如:87/5
0x8*10 + 0x7 = 0x57
0x57/5 = 0x11 remains 0x7
Run Code Online (Sandbox Code Playgroud)
这些指令的原因是因为在过去,记忆很昂贵,你必须尽可能减少内存使用.因此在那个时代,CISC CPU非常普遍.他们使用大量复杂的指令来最小化用于执行任务的指令.如今,内存便宜得多,而现代架构几乎就是RISC,与CPU复杂性和代码密度相冲突