#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# daa and das

Member Posts: 10
Can somebody explain these instructions to me? When and why are they used? Thanks!

• Member Posts: 1,666
: Can somebody explain these instructions to me? When and why are they used? Thanks!
:

No offense, but for the most part they aren't. They are used for BCD (Binary Coded Decimal) arithmetic, but as noone really uses that anymore, those opcodes aren't used often. Nowadays they are sometimes used for little tricks.

"We can't do nothing and think someone else will make it right."

• Member Posts: 10
Okay, in this code:

> hex2asc:
> push ax ; save al = 0xa9
> shr al,1
> shr al,1
> shr al,1
> shr al,1 ; high nibble --> low nibble, al = 0x0a
> daa
> daa ; al = ascii = 0x41 (="A")
> mov bx,[buffpt]
> mov [bx],al
> inc bx
> mov [buffpt],bx
> pop ax ; restore al = 0xa9
> and al,0x0f ; mask high nibble, al = 0x09
> daa
> daa ; al = ascii = 0x39 (="9")
> mov bx,[buffpt]
> mov [bx],al
> inc bx
> mov [buffpt],bx
> ret

What do those four DAA instructions do?
• Member Posts: 1,666
: Okay, in this code:
:
: > hex2asc:
: > push ax ; save al = 0xa9
: > shr al,1
: > shr al,1
: > shr al,1
: > shr al,1 ; high nibble --> low nibble, al = 0x0a
: > daa
: > daa ; al = ascii = 0x41 (="A")
: > mov bx,[buffpt]
: > mov [bx],al
: > inc bx
: > mov [buffpt],bx
: > pop ax ; restore al = 0xa9
: > and al,0x0f ; mask high nibble, al = 0x09
: > daa
: > daa ; al = ascii = 0x39 (="9")
: > mov bx,[buffpt]
: > mov [bx],al
: > inc bx
: > mov [buffpt],bx
: > ret
:
: What do those four DAA instructions do?
:

First off here's the algorithm that DAA performs
[code]
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
[/code]

You would perform this after adding two packed BCD numbers together in binary (ie with add). Packed BCD numbers use 4 bits to represent one decimal digit. The high nibble represents the 10's place and the low nibble represents the 1's place and the greatest value that a byte can hold in BCD is 99 represented as 0x99. Here's a simple example that should make it fairly clear what DAA does.

Suppose you add 1 and 9. The result would be 0xA. If you were to then perform daa you would get

0xA > 0x9 therefore al=al+6 (0xA + 6 = 0x10).
So it just converts the hex value into a BCD number by adding 6 (10 + 6 = 16 = 0x10) if the low nibble is above 9, and it does the same for the high nibble. A place where BCD may be useful is embedded programming where you are controlling the logic for those 8 section LED lights (like digital clocks). But otherwise you'll probably NEVER use it.

In this case it's being used as a trick to convert values less than 9 to ASCII values '0'-'9' (0x30-0x39) and values greater than 9 to ASCII values 'A'-'F' (0x41-0x46). This only works because they are exactly 0x11 apart (if they were 0x10 apart changing the adc to add would also work, but if they were 0x12 apart then it wouldn't work at all).

mov al, anibble add al, 0x30
daa
would be value between BCD 30-45. 0-9 would be 30-39 and A-F would be 40-45. Alas, we need that one so we use 130 to set the carry flag.

As you can see, this is one of those tricks I was talking about as this isn't what daa was meant for. However there is a hidden form of aam and aad that can be useful.

"We can't do nothing and think someone else will make it right."