how does AAA work in 8086 instruction set?
Asked Answered
C

1

5

There is some info regarding the algorithm how the instruction works:

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

But the problem i am facing is when I replace 15 in the above example with numbers like 00FF and 00FA the value in AH gets incremented by 02 instead of 01 !!

Why are these changes ??

Cobol answered 22/9, 2013 at 15:6 Comment(6)
You are supposed to use it only after an ADD. Using BCD arithmetic made sense 35 years ago, those days are long gone.Basseterre
A value of 00FF and 00FA is not a legal input for the AAA instruction. The highest legal value of AL is 18h.Cal
I believe the purpose of AAA is to add 2 BCD digits at a time (that's what the AF or half carry is for), FF being a legal input value (e.g. result of 99 + 66).Fortify
The AAA instruction doesn't add BCD digits, but makes any needed digit overflow adjustment after such an addition. If you read the AAA instruction description thoroughly, it says, The AAA instruction is only useful when it follows an ADD instruction that adds (binary addition) two unpacked BCD values and stores a byte result in the AL register. In your example of 00FF and 00FA, these numbers can't be generated by an BCD ADD operation.Voracious
Where did you get that example? MOV doesn't set flags, so you're using AF with whatever value it held before. See also the insn set ref manual entry for AAA for the same pseudo-code but indented properly, plus a text description of how to use it. Links to x86 manuals/guides/docs in the x86 tag wiki.Vomitory
Possible duplicate of How do ASCII Adjust and Decimal Adjust instructions work?Mcqueen
A
7

Here is the detailed explanation of DAA and AAA :

The aaa (ASCII adjust after addition) and daa (decimal adjust for addition) instructions support BCD arithmetic. BCD values are decimal integer coded in binary form with one decimal digit (0..9) per nibble. ASCII (numeric) values contain a single decimal digit per byte, the H.O. nibble of the byte should contain zero.

The aaa and daa instructions modify the result of a binary addition to correct it for ASCII or decimal arithmetic. For example, to add two BCD values, you would add them as though they were binary numbers and then execute the daa instruction afterwards to correct the results. Likewise, you can use the aaa instruction to adjust the result of an ASCII addition after executing an add instruction. Please note that these two instructions assume that the add operands were proper decimal or ASCII values. If you add binary (non-decimal or non-ASCII) values together and try to adjust them with these instructions, you will not produce correct results.

The choice of the name "ASCII arithmetic" is unfortunate, since these values are not true ASCII characters. A name like "unpacked BCD" would be more appropriate. However, Intel uses the name ASCII, so this text will do so as well to avoid confusion. However, you will often hear the term "unpacked BCD" to describe this data type.

Aaa (which you generally execute after an add, adc, or xadd instruction) checks the value in al for BCD overflow. It works according to the following basic algorithm:

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

The aaa instruction is mainly useful for adding strings of digits where there is exactly one decimal digit per byte in a string of numbers. This text will not deal with BCD or ASCII numeric strings, so you can safely ignore this instruction for now. Of course, you can use the aaa instruction any time you need to use the algorithm above, but that would probably be a rare situation.

The daa instruction functions like aaa except it handles packed BCD (binary code decimal) values rather than the one digit per byte unpacked values aaa handles. As for aaa, daa's main purpose is to add strings of BCD digits (with two digits per byte). The algorithm for daa is

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

So AAA works only in case of one decimal digit per byte which is not the case you mentioned above.

Alkalinity answered 6/12, 2016 at 7:37 Comment(3)
Can't you use AAA on actual ASCII data? It checks (AL AND 0FH) || AF to detect carry-out from a digit, so it shouldn't be fooled by having the 0x30 bits set. (ASCII '0' = 0x30 = 48, so all ten ASCII digits have their integer value in the low nibble) .Vomitory
Also, HTML extract of the official docs: felixcloutier.com/x86/AAA.htmlVomitory
You can actually use ASCII numbers in the range 0x30-0x39. After the AAA instruction, you need to OR the result with 0x30 if you need an ASCII result.Copacetic

© 2022 - 2024 — McMap. All rights reserved.