关于算法如何工作的信息有一些信息
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.
Example:
MOV AX, 15 ; AH = 00, AL = 0Fh
AAA ; AH = 01, AL = 05
RET
但我遇到的问题是当我在上面的例子中用00FF和00FA等数字替换15时,AH中的值增加02而不是01 !!
是这些变化吗?
答案 0 :(得分:4)
以下是 DAA和AAA 的详细说明:
aaa(添加后的ASCII调整)和daa(添加的十进制调整)指令支持BCD算法。 BCD值是以二进制形式编码的十进制整数,每个半字节有一个十进制数字(0..9)。 ASCII(数字)值每个字节包含一个十进制数字,H.O。字节的半字节应该包含零。
aaa和daa指令修改二进制加法的结果,以便对ASCII或十进制算术进行校正。例如,要添加两个BCD值,您可以将它们添加为二进制数,然后执行daa指令以更正结果。同样,您可以在执行add指令后使用aaa指令调整ASCII添加的结果。请注意,这两条指令假定添加操作数是正确的十进制或ASCII值。如果将二进制(非十进制或非ASCII)值一起添加并尝试使用这些指令进行调整,则无法生成正确的结果。
选择名称" ASCII算法"很不幸,因为这些值不是真正的ASCII字符。像"解压缩的BCD"会更合适。但是,英特尔使用名称ASCII,因此本文也会这样做,以避免混淆。但是,您经常会听到“解压缩BCD”这个术语。描述这种数据类型。
Aaa(通常在add,adc或xadd指令之后执行)检查al中的值以获取BCD溢出。它的工作原理如下:
if ( (al and 0Fh) > 9 or (AuxC =1) ) then
if (8088 or 8086) then
al := al + 6
else
ax := ax + 6
endif
ah := ah + 1
AuxC := 1 ;Set auxilliary carry
Carry := 1 ; and carry flags.
else
AuxC := 0 ;Clear auxilliary carry
Carry := 0 ; and carry flags.
endif
al := al and 0Fh
aaa指令主要用于添加数字串,其中一串数字中每个字节只有一个十进制数字。本文不会处理BCD或ASCII数字字符串,因此您现在可以放心地忽略此指令。当然,您可以在需要使用上述算法的任何时候使用aaa指令,但这可能是一种罕见的情况。
daa指令的功能类似于aaa,除了它处理打包的BCD(二进制代码十进制)值,而不是每个字节的一个数字解压缩值aaa处理。至于aaa,daa的主要目的是添加BCD数字串(每个字节有两位数)。 daa的算法是
if ( (AL and 0Fh) > 9 or (AuxC = 1)) then
al := al + 6
AuxC := 1 ;Set Auxilliary carry.
endif
if ( (al > 9Fh) or (Carry = 1)) then
al := al + 60h
Carry := 1; ;Set carry flag.
endif
因此AAA仅在每个字节有一个十进制数字的情况下工作,这与上面提到的情况不同。