name "huge"
; this example shows how to add huge unpacked bcd numbers.
; this allows to over come the 16 bit and even 32 bit limitation.
; because 32 digit decimal value holds over 100 bits!
; with some effort the number of digits can be increased.
datas segment 'data'
; the number of digits in numbers:
; it's important to reserve 0 as most significant digit, to avoid overflow.
; so if you need to operate with 250 digit values, you need to declare len = 251
len equ 32
; every decimal digit is stored in a separate byte.
; first number is: 423454612361234512344535179521
num1 db 0,0,4,2,3,4,5,4,6,1,2,3,6,1,2,3,4,5,1,2,3,4,4,5,3,5,1,7,9,5,2,1
; second number is: 712378847771981123513137882498
num2 db 0,0,7,1,2,3,7,8,8,4,7,7,7,1,9,8,1,1,2,3,5,1,3,1,3,7,8,8,2,4,9,8
; we will calculate this:
; sum = num1 + num2
; 423454612361234512344535179521 + 712378847771981123513137882498 =
; = 1135833460133215635857673062019
sum db len dup(0) ;declare array to keep the result.
datas ends
code_segment segment 'code'
assume cs:code_segment,ds:datas
start: mov ax,datas
mov ds,ax
; digit pointer:
xor bx, bx
; setup the loop:
mov cx, len
mov bx, len-1 ; point to lest significant digit!
next_digit:
; add digits:
mov al, num1[bx]
adc al, num2[bx]
; this is a very useful instruction that
; adjusts the value of addition
; to be string compatible
aaa
; aaa stands for ascii add adjust.
; --- algorithm behind aaa ---
; if low nibble of al > 9 or af = 1 then:
; al = al + 6
; ah = ah + 1
; af = 1
; cf = 1
; else
; af = 0
; cf = 0
;
; in both cases: clear the high nibble of al.
; --- end of aaa logic ---
; store result:
mov sum[bx], al
; point to next digit:
dec bx
loop next_digit
; include carry in result (if any):
adc sum[bx], 0
; print out the result:
mov cx, len
; start printing from most significant digit:
mov bx, 0
print_d:
mov al, sum[bx]
; convert to ascii char:
or al, 30h
mov ah, 0eh
int 10h
inc bx
loop print_d
; wait for any key press:
mov ah,0
int 16h
;return control to the operating system (stop program).
mov ah,4ch
int 21h
code_segment ends
end start
; this example shows how to add huge unpacked bcd numbers.
; this allows to over come the 16 bit and even 32 bit limitation.
; because 32 digit decimal value holds over 100 bits!
; with some effort the number of digits can be increased.
datas segment 'data'
; the number of digits in numbers:
; it's important to reserve 0 as most significant digit, to avoid overflow.
; so if you need to operate with 250 digit values, you need to declare len = 251
len equ 32
; every decimal digit is stored in a separate byte.
; first number is: 423454612361234512344535179521
num1 db 0,0,4,2,3,4,5,4,6,1,2,3,6,1,2,3,4,5,1,2,3,4,4,5,3,5,1,7,9,5,2,1
; second number is: 712378847771981123513137882498
num2 db 0,0,7,1,2,3,7,8,8,4,7,7,7,1,9,8,1,1,2,3,5,1,3,1,3,7,8,8,2,4,9,8
; we will calculate this:
; sum = num1 + num2
; 423454612361234512344535179521 + 712378847771981123513137882498 =
; = 1135833460133215635857673062019
sum db len dup(0) ;declare array to keep the result.
datas ends
code_segment segment 'code'
assume cs:code_segment,ds:datas
start: mov ax,datas
mov ds,ax
; digit pointer:
xor bx, bx
; setup the loop:
mov cx, len
mov bx, len-1 ; point to lest significant digit!
next_digit:
; add digits:
mov al, num1[bx]
adc al, num2[bx]
; this is a very useful instruction that
; adjusts the value of addition
; to be string compatible
aaa
; aaa stands for ascii add adjust.
; --- algorithm behind aaa ---
; if low nibble of al > 9 or af = 1 then:
; al = al + 6
; ah = ah + 1
; af = 1
; cf = 1
; else
; af = 0
; cf = 0
;
; in both cases: clear the high nibble of al.
; --- end of aaa logic ---
; store result:
mov sum[bx], al
; point to next digit:
dec bx
loop next_digit
; include carry in result (if any):
adc sum[bx], 0
; print out the result:
mov cx, len
; start printing from most significant digit:
mov bx, 0
print_d:
mov al, sum[bx]
; convert to ascii char:
or al, 30h
mov ah, 0eh
int 10h
inc bx
loop print_d
; wait for any key press:
mov ah,0
int 16h
;return control to the operating system (stop program).
mov ah,4ch
int 21h
code_segment ends
end start
No comments:
Post a Comment