我一直在努力理解来自x86汇编语言的ASCII调整指令。
我看到整个互联网信息告诉我不同的事情,但我想这是以不同形式解释的同样的事情,我仍然没有。
任何人都可以解释为什么在AAA
的伪代码中,AAS
我们必须添加,从AL中的低位半字节中减去6?
有人可以解释AAM
,AAD
和十进制调整指令伪代码in the Intel instruction set manuals,他们为什么会这样,他们背后的逻辑是什么?
最后,有人可以举例说明这些说明是否有用,或者至少在过去它们有用的应用程序中。
我知道现在没有使用这些说明,但我仍然想知道这些说明是如何工作的,很高兴知道。
答案 0 :(得分:7)
为什么在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)
执行解压缩添加是相同的,除了您直接从单位数字到十位数,丢弃每个字节的顶部半字节
有关详细信息,请阅读
并且有人可以在英特尔指令集手册中解释AAM,AAD和Decimal调整指令伪代码,他们为什么这样,他们背后的逻辑是什么?
AAM只是从二进制到BCD的转换。你通常以二进制形式进行乘法,然后调用AAM将结果除以10,并将商 - 余数对存储在两个未压缩的BCD字符中
例如:
13*6 = 78 = 0100 1110
78/10 = 7 remains 8 => result = 0x78
AAD是相反的:在除法之前,你调用AAD将它从BCD转换为二进制并像其他二进制除法一样进行除法
例如:87/5
0x8*10 + 0x7 = 0x57
0x57/5 = 0x11 remains 0x7
这些指令的原因是因为在过去,记忆很昂贵,你必须尽可能减少内存使用量。因此在那个时代CISC CPU很常见。他们使用大量复杂的指令来最小化用于执行任务的指令。如今,内存便宜得多,现代架构几乎是RISCy,与CPU复杂性和代码密度相冲突
答案 1 :(得分:0)
我写了一个程序,可以帮助您理解加法后的AAA。
.model small
.data
a db '1234'
len1 db $-a
b db '9876'
len2 db $-b
result db 05 dup(?)
len3 db $-result
.code
main proc near
mov ax,@data
mov ds,ax
lea bx,a
add bl,len1
mov si,bx
lea bx,b
add bl,len2
mov di,bx
dec si
dec di
dec len3
lea bx,result
add bl,len3
mov cl,len1
mov ax,0h
l1:
mov al,[si]
mov dl,[di]
cmp ah,00h
je skip
mov ah,0h
inc al
skip:
add al,dl
aaa
or al,30h
mov [bx],al
dec bx
dec si
dec di
loop l1
cmp ah,00h
je over
mov [bx],31h
jmp finish
over:
mov [bx],30h
finish:
mov ax,04ch
int 21h
endp
end
现在,正如您在程序中看到的“ add”指令之后,我们正在使用“ aaa”将数字转换为ASCII(30-39对应于0-9)。因此,编写实际输出时,我们实际上需要将其返回十六进制,以便我们得出答案的“或”。现在,使用“ si”和“ di”逐位加载数字,并检查是否存在进位,因为当我们执行“ aaa”时我们将知道,因为当数字大于9时,它将生成数字ah,因此我们将“ inc ”。请在下面查看“ aaa”的工作原理。
AAA (ASCII Adjust after Addition)
if low nibble of AL > 9 or AF = 1 then:
AL = AL + 6
AH = AH + 1
AF = 1
CF = 1
else
AF = 0
CF = 0
in both cases:
clear the high nibble of AL.
有关ASCII加,减,乘和除的更多程序,请检查此链接。 GitHub