AAA如何在8086指令集中工作?

时间:2013-09-22 15:06:48

标签: assembly masm

关于算法如何工作的信息有一些信息

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 !!

是这些变化吗?

1 个答案:

答案 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仅在每个字节有一个十进制数字的情况下工作,这与上面提到的情况不同。