/* personal notes of renzo diomedi */

~ 00001110 ~




Decimal Arithmetic Binary Coded Decimal (BCD) format is a popular method to handle humanreadable numbers, and quickly process them in the processor. Although much of the advanced BCDhandling operations are located in the FPU, the core processor contains some simplistic instructions for performing arithmetic using BCD values. This section describes the basic BCD arithmetic instructions available, and demonstrates how they are used within the assembly language program.
Unpacked BCD arithmetic
unpacked BCD values contain a single decimal digit (0 through 9) in a byte. Multiple decimal digits are stored in multiple bytes, 1 byte per digit. When an application is required to perform a mathematical operation on the unpacked BCD values, it is assumed that the result should also be in unpacked BCD format. Fortunately, the IA-32 platform provides special instructions for producing unpacked BCD results from common mathematical operations.
Four instructions are used to convert binary arithmetic results to unpacked BCD format:
❑ AAA: Adjusts the result of an addition process
❑ AAS: Adjusts the result of a subtraction process
❑ AAM: Adjusts the result of a multiplication process
❑ AAD: Prepares the dividend of a division process
These instructions must be used in combination with the normal unsigned integer ADD, ADC, SUB, SBB, MUL, and DIV instructions. The AAA, AAS, and AAM instructions are used after their respective operation to convert a binary result into unpacked BCD format. The AAD instruction is somewhat different in that it is used before the DIV instruction to prepare the dividend value to produce an unpacked BCD result. Each of these instructions uses an implied operand, the AL register. The AAA, AAS, and AAM instructions assume that the previous operation result is placed in the AL register, and converts that value to unpacked BCD format. The AAD instruction assumes that the dividend value is placed in the AX register in unpacked BCD format, and converts it to binary format for the DIV instruction to handle. The result is a proper unpacked BCD value, the quotient in the AL register, and the remainder in the AH register (in unpacked BCD format).





windows environment

aaa.s

aaa.o

aaa.exe


The unpacked BCD values are stored in memory locations in little-endian format. The first value is read into the AL register 1 byte at a time, and added with the same place value of the second value using the ADC instruction. The ADC instruction is used to ensure that any carry bits are added from the previous additions (don’t forget the CLC instruction before the loop to ensure that the carry flag is cleared). The AAA instruction is used after the ADC instruction to convert the binary result in the AL register to unpacked BCD format before it is stored in the same place value location in the sum location. The ECX register is used to count the value places so the LOOP instruction knows when to quit.

Breakpoint 1, ?? () at users\rnz\desktop\aaa.s:10
10 nop
(gdb) s
11 xor %edi, %edi
(gdb) s
12 movl $5, %ecx
(gdb) s
13 clc # to clear the carry flag
(gdb) s
loop1 () at users\rnz\desktop\aaa.s:15
15 movb value1(, %edi, 1), %al
(gdb) s
16 adcb value2(, %edi, 1), %al
(gdb) s
17 aaa
(gdb) s
18 movb %al, sum(, %edi, 1)
(gdb) s
19 inc %edi
(gdb) s
20 loop loop1
(gdb) s
15 movb value1(, %edi, 1), %al
(gdb) s
16 adcb value2(, %edi, 1), %al
(gdb) s
17 aaa
(gdb) x/6b &sum
0x403000 : 8 0 0 0 0 0
(gdb) s
18 movb %al, sum(, %edi, 1)
(gdb) s
19 inc %edi
(gdb) s
20 loop loop1
(gdb) x/6b &sum
0x403000 : 8 5 0 0 0 0
(gdb) info reg
eax 0x60ff05 6356741
ecx 0x4 4
edx 0x401000 4198400
ebx 0x297000 2715648
esp 0x60ff74 0x60ff74
ebp 0x60ff80 0x60ff80
esi 0x401000 4198400
edi 0x2 2
eip 0x401020 0x401020
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x53 83
gs 0x2b 43
(gdb)
(gdb) s
18 movb %al, sum(, %edi, 1)
(gdb) s
19 inc %edi
(gdb) s
20 loop loop1
(gdb) s
15 movb value1(, %edi, 1), %al
(gdb) s
16 adcb value2(, %edi, 1), %al
(gdb) s
17 aaa
(gdb) x/6b &sum
0x403000 : 8 5 0 0 0 0
(gdb) s
18 movb %al, sum(, %edi, 1)
(gdb)
19 inc %edi
(gdb)
20 loop loop1
(gdb)
15 movb value1(, %edi, 1), %al
(gdb)
16 adcb value2(, %edi, 1), %al
(gdb)
17 aaa
(gdb)
18 movb %al, sum(, %edi, 1)
(gdb)
19 inc %edi
(gdb)
20 loop loop1
(gdb)
21 adcb $0, sum(, %edi, 4)
(gdb)
22 movl $1, %eax
(gdb)
23 movl $0, %ebx
(gdb)
24 int $0x21
(gdb)
Program received signal SIGSEGV, Segmentation fault.
loop1 () at users\rnz\desktop\aaa.s:24
24 int $0x21
(gdb)
(gdb) info reg
eax 0x1 1
ecx 0x0 0
edx 0x401000 4198400
ebx 0x0 0
esp 0x60ff74 0x60ff74
ebp 0x60ff80 0x60ff80
esi 0x401000 4198400
edi 0x5 5
eip 0x401034 0x401034
eflags 0x10246 [ PF ZF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x53 83
gs 0x2b 43
(gdb) x/6b &sum
0x403000 : 8 5 0 1 8 0
(gdb)



Home Page