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.
| Subtract | Binary result | After DAS | CF |
|---|---|---|---|
| 52h − 17h | 3Bh (AF = 1) | 35h | 0 |
| 40h − 01h | 3Fh (AF = 1) | 39h | 0 |
| 17h − 52h | C5h (CF = 1) | 65h | 1 (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.
MOV AL, 52h ; packed BCD 52SUB AL, 17h ; AL = 3Bh, not BCDDAS ; AL = 35h: packed 35MOV AH, ALMOV CL, 4SHR AH, CL ; AH = high digitAND AL, 0Fh ; AL = low digitOR AX, 3030h ; both digits -> charactersMOV BX, AXMOV DL, BHMOV AH, 02h ; DOS: print DLINT 21hMOV DL, BLMOV AH, 02hINT 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.