Intro
The following assembly language program is for MASM 5.1 up calculates factorial of numbers upto 255!, that is quite a large number to compute a factorial. See below:
Number:255
Factorial
3350850684932979117652665123754814942022
5840635917407025767798842862087990357327
7100562613812676331425928080211850228244
5926550135522251856727692533193070412811
0833303256593220417000297921662507342533
9051375446604571124033846270103402026299
2581378423147276636643647155396305352541
1055414394348401099150682854306750685916
3858198060416294038335658673919826878210
4924614076605793562865241982176207428620
9697768031494674313868079724382476891586
5600000000000000000000000000000000000000
0000000000000000000000000
for the Faint HeartedThe program calculates and computes big numbers by simulating the traditional way of multiplication and division of numbers. Hence it can do this upto any number of digits as much as the memory can hold. In this example, I have used 512 digited numbers, which is more than enough for holding 255
!.
The key parts of the following program is
bignum_mul and
bignum_add macro which simulates the traditional method of multiplying and adding numbers (not using any vedic maths, which can certainly improve the efficiency I guess).
The following is the assembly language program, try digesting...
.asm Program
data segment
b1 db 512 dup(0)
b2 db 512 dup(0)
msg db 0dh,0ah,"Number:$"
fac db 0dh,0ah,"Factorial",0dh,0ah,"$"
data ends
bignum_get macro var
local exit,get,loo,skip
xor cx,cx
lea si,var
mov di,si
mov ah,01h
get:
int 21h
cmp al,0dh
je exit
sub al,30h
mov [si],al
inc si
inc cx
jmp get
exit:
shr cx,1
jz skip
dec si
loo:
mov ah,[si]
mov al,[di]
mov [si],al
mov [di],ah
dec si
inc di
loop loo
skip:
endm
geti macro
local exit,get
xor bx,bx
mov dx,bx
mov cx,00ah
get:
push bx
;Read character
mov ah,01h
int 21h
xor ah,ah
pop bx
;If enter stop
cmp al,0dh
jz exit
sub al,30h
;Multply By 10
push ax
mov ax,bx
mul cx
mov bx,ax
pop ax
;add
add bx,ax
;redo
jmp get
exit:
mov ax,bx
endm
bignum_put macro var
local put,en,nxt,exit
lea si,var
mov di,si
mov cx,0200h
add di,cx
dec di
en:
cmp BYTE PTR [di],00h
jne nxt
dec di
jmp en
nxt:
mov ah,02h
put:
mov dl,[di]
add dl,30h
int 21h
cmp si,di
je exit
dec di
loop put
exit:
endm
bignum_add macro b1,b2
local ader,exit
lea si,b1
lea di,b2
mov cx,0200h
mov bl,10
ader:
mov al,[di]
mov ah,[si]
add al,ah
jz exit
xor ah,ah
div bl
mov [si],ah
inc si
add [si],al
inc di
loop ader
exit:
endm
bignum_mul macro b1
local loo,exit
cmp dl,01h
jz exit
lea si,b1
mov dh,10
xor bx,bx
mov cx,0200h
loo:
mov al,[si]
xor ah,ah
mul dl
add ax,bx
div dh
mov [si],ah
inc si
mov bl,al
loop loo
exit:
endm
puts macro msg
push ax
push dx
mov dx,offset msg
mov ah,09h
int 21h
pop dx
pop ax
endm
assume cs:code,ds:data
code segment
start:
mov ax,data
mov ds,ax
lea si,b1
mov BYTE PTR [si],01h
puts msg
geti
mov dl,al
loo:
push dx
bignum_mul b1
pop dx
dec dl
jnz loo
puts fac
bignum_put b1
mov ah,4ch
int 21h
code ends
end start
The Simple Factorial code upto
8!
geti macro
local exit,get
xor bx,bx
mov dx,bx
mov cx,00ah
get:
push bx
;Read character
mov ah,01h
int 21h
xor ah,ah
pop bx
;If enter stop
cmp al,0dh
jz exit
sub al,30h
;Multply By 10
push ax
mov ax,bx
mul cx
mov bx,ax
pop ax
;add
add bx,ax
;redo
jmp get
exit:
mov ax,bx
endm
puti macro buffer
local exit,put
mov bx,0ah
lea si,buffer
add si,06h
mov BYTE PTR [si],'$'
put:
xor dx,dx
dec si
div bx
add dl,30h
mov [si],dl
cmp ax,0h
jnz put
mov dx,si
mov ah,09h
int 21h
endm
puts macro msg
push ax
push dx
mov dx,offset msg
mov ah,09h
int 21h
pop dx
pop ax
endm
data segment
msg1 db 0dh,0ah,"Enter Number : $"
msg2 db 0dh,0ah,"Factorial : $"
buff db 20 dup(?)
data ends
assume cs:code,ds:data
code segment
start:
mov ax,data
mov ds,ax
puts msg1
geti
push ax
puts msg2
pop ax
mov cx,ax
dec cx
jz over
xor dx,dx
re:mul cx
loop re
over:
puti buff
mov ah,4ch
int 21h
code ends
end start
Thanks to ABA (Bellari) for challenging me to do the 255!.. Yo!!!