The code from chapter 7 of Intel assembly language programming (fifth edition) uses the AAA (ASCII adjust after addition) command to adjust the results after the ASCII addition. The source code is as follows:
Title ASCII addition (ascii_add.asm)
; Perform ASCII arithmetic on strings having
; An implied fixed decimal point
Include irvine32.inc
Decimal_offset = 5; offset from right of string
. Data
Decimal_one Byte "100123456789765"; 1001234567.89765
Decimal_two Byte "900402076502015"; 9004020765.02015
Sum byte (sizeof decimal_one + 1) DUP (0), 0
. Code
Main proc
; Start at the last digit position.
MoV ESI, sizeof decimal_one-1
MoV EDI, sizeof decimal_one
MoV ECx, sizeof decimal_one
MoV BH, 0; Set carry value to zero
L1:
MoV ah, 0; clear Ah before addition
MoV Al, decimal_one [esi]; get the first digit
Add Al, BH; Add the previous carry
AAA; adjust the sum (Ah = carry)
MoV BH, Ah; Save the carry in carry1
Or BH, 30 h; convert it to ASCII
Add Al, decimal_two [esi]; add the second digit
AAA; adjust the sum (Ah = carry)
Or BH, Ah; or the carry with carry1
Or BH, 30 h; convert it to ASCII
Or Al, 30 h; Convert Al back to ASCII
MoV sum [EDI], Al; save it in the sum
Dec ESI; back up one digit
Dec EDI
Loop L1
MoV sum [EDI], BH; save last carry Digit
; Display the sum as a string.
MoV edX, offset sum
Call writestring
Call CRLF
Exit
Main endp
End main
Next, we will start to analyze them one by one.
Decimal_one Byte "100123456789765"; 1001234567.89765
Decimal_one Byte "900402076502015"; 9004020765.02015
Sum byte (sizeof decimal_one + 1) DUP (0), 0
First, two numeric strings are defined to implicitly Add the decimal point. Then a sum variable is defined, which has one more bit to place carry.
Then let's look at the code segment:
MoV ESI, sizeof decimal_one-1
MoV EDI, sizeof decimal_one
MoV ECx, sizeof decimal_one
MoV BH, 0; Set carry value to zero
First, assign a value to the loop cursor ESI as the last position of the string, that is, sizeof decimal_one-1. At this time, it points to the last digit "5" of decimal_one ". Next is the sum cursor EDI, which is assigned a value of sizeof decimal_one (because we have one more bit longer than decimal_one to store carry), and the number of cycles ECx, the value is the length of decimal_one.
Finally, set the carry value BH to zero.
Then let's take a look at the following code:
L1:
MoV ah, 0; you must clear Ah before executing the AAA command; otherwise, the AAA command result will be affected.
MoV Al, decimal_one [esi]; returns the number of the ESI position of decimal_one.
Add Al, BH; Add the previous carry value to Al (for example, there is no carry value when it is first added)
AAA; Use AAA to adjust the addition result and save the value to ah.
MoV BH, Ah; Save the bitwise value to BH
Or BH, 30 h; convert the result to ASCII code
Add Al, decimal_two [esi]; then add the decimal_two ESI digit and save it to Al.
AAA; adjust the addition result and save the carry to ah.
Or BH, Ah; perform or operate the current carry (not quite clear why)
Or BH, 30 h; convert the bitwise value into ASCII code
Or Al, 30 h; convert values in Al to ASCII code
MoV sum [EDI], Al; assign the calculated value to the corresponding bit of sum.
Dec ESI; move one digit forward to get the cursor position of the next addition number
Dec EDI; move one digit forward to obtain the cursor position of the next addition number
Loop L1; execute the next loop
MoV sum [EDI], BH; after calculation, add the last carry to the EDI position of sum.
; Display the sum as a string.
MoV edX, offset sum; assign the offset address of sum to EDX.
Call writestring; display the edX value on the screen, that is, the result of sum.
Call CRLF; move the cursor to the beginning of the next line
Exit; exit (function in irvine32)
At this point, the program analysis is complete and the results of the program will be:
1000525533291780
The result is a total of 16 bits (the original two are added as 15 bits), and the decimal point is hidden.
Supplement:
Because the highest bit in the ASCII code decimal number is always 0011b, or BH, 30 h is performed; the four-digit high ASCII code decimal number is not set to the uncompressed format for bits, and then the ASCII format is set. The example is as follows:
ASCII format: 33 34 30 32
Uncompressed format: 03 04 00 02