DAS follows a SUB (or SBB) of two packed BCD bytes into AL and corrects the binary difference into a packed BCD one. For example 52h − 17h is 3Bh in binary, and DAS changes it to 35h, which is 52 − 17 in decimal.

Exactly what it does

First, if the low digit of AL is greater than 9 or AF is 1, DAS subtracts 6 from AL and sets AF. Then, if AL is greater than 9Fh or CF is 1, it subtracts 60h from AL and sets CF. A step that is not needed clears its flag. CF = 1 means the second number was larger: a decimal borrow, to be taken from the next pair of digits. SF, ZF and PF are set from the final AL; OF is undefined.

SubtractBinary resultAfter DASCF
52h − 17h3Bh (AF = 1)35h0
40h − 01h3Fh (AF = 1)39h0
17h − 52hC5h (CF = 1)65h1 (borrow)

The last row reads as 117 − 52 = 65 with a borrow out: the result is the hundred's complement of 35, the usual form of a negative BCD result.

Prints 35.
MOV AL, 52h ; packed BCD 52
SUB AL, 17h ; AL = 3Bh, not BCD
DAS ; AL = 35h: packed 35
MOV AH, AL
MOV CL, 4
SHR AH, CL ; AH = high digit
AND AL, 0Fh ; AL = low digit
OR AX, 3030h ; both digits -> characters
MOV BX, AX
MOV DL, BH
MOV AH, 02h ; DOS: print DL
INT 21h
MOV DL, BL
MOV AH, 02h
INT 21h

Longer numbers

For multi-byte packed numbers, subtract from the lowest byte up with SBB, DAS after each byte, and the borrow travels in CF.

Pitfalls

Only AL is adjusted, and only right after the subtraction, because DAS relies on the AF and CF it left behind. DEC does not set CF, so a decimal count-down is SUB AL, 1 followed by DAS.

Later CPUs

Unchanged in 16- and 32-bit code; not available in 64-bit mode.