A program that will test the Nonrecursive Factorial procedure using a value passed in by the program user and will also do a time comparision of the Nonrecursive and Recursive Factorial functions.
Nonrecursive Factorial & Factorial Comparison
TITLE: NonrecursiveFactorial&FactorialComparison (Factorials.asm)
;------------------------------------------------------------
; Name:
;
; Filename: Factorials.asm
;
; Project #: 6
;
; Completed: March 15, 2003
;
; Description: My sixth assembly program. A program that will
; test the Nonrecursive Factorial procedure using
; a value passed in by the program user and will
; also do a time comparision of the Nonrecursive
; and Recursive Factorial functions.
; From Assembly Language For Intel-Based Computers,
; 4th Ed. by Kip R. Irvine.
; (Problem #3 and #4 on pg. 298)
;
; Reference: Assembly Language For Intel-Based Computers,
; 4th Ed. by Kip R. Irvine
; (Section 8.5.2 Calculating a Factorial)
; (Fact.asm)
;------------------------------------------------------------
INCLUDE Irvine32.inc
.data
startTime dword 0
savedNum sdword ?
numOfTimes = 00000FFFh;(squared) to calculate the factorial
caseTable byte '1' ;lookup value
dword enterInt ;address of lookup value
entrySize = ($ - caseTable )
byte '2'
dword factCompare
byte '3'
dword endTest
numberOfEntries = 3
msgIntro byte "This is Your Name's sixth assembly program. A program that will",0dh,0ah
byte "test the Nonrecursive Factorial procedure using a value passed in",0dh,0ah
byte "by the program user and will also do a time comparision of the ",0dh,0ah
byte "Nonrecursive and Recursive Factorial functions.",0dh,0ah,0
msgSelMn byte " -----------------------------------------",0dh,0ah
byte "| MENU: |",0dh,0ah
byte "| 1. NonRecursive Factorial (Exercise #3) |",0dh,0ah
byte "| 2. Factorial Comparison (Exercise #4) |",0dh,0ah
byte "| 3. Exit Program |",0dh,0ah
byte " -----------------------------------------",0dh,0ah
byte "Enter Selection: ",0
msgInputN byte "Enter the value of n to calculate. "
byte "( n must be <= 12 ) : ",0
msgFact byte "Factorial = ",0
msgError byte "Sorry cannot calculate the following factorial because "
byte "it is greater than 12! ",0dh,0ah
byte " 12 < ",0
msgNonRec byte "The time to do the Nonrecursive factorial = ",0
msgRec byte "The time to do the Recursive factorial = ",0
msgEnd byte "End Program",0dh,0ah,0
.code
main PROC
;///////Intro Message/////////////////////////////////
mov edx,OFFSET msgIntro ;intro message into edx
call WriteString ;display msgIntro
call Crlf ;endl
call WaitMsg ;pause message
call Clrscr ;clear screen
call Menu ;menu procedure
ExitProg::exit ;global label to exit
main ENDP
;------------------------------------------------
Menu PROC
;
; Receives: Nothing
; Returns: Nothing
;------------------------------------------------
mov edx,OFFSET msgSelMn ;ask user for input
call WriteString ;display msgSelMn
call ReadChar ;read one character
call Clrscr
mov ebx,OFFSET caseTable;point EBX to the table
mov ecx,numberOfEntries ;loop counter
L1:
cmp al,[ebx] ;match found?
jne L2 ;no: continue
call NEAR PTR [ebx + 1] ;yes: call the procedure
call WriteString ;display message
call Crlf ;endl
call Clrscr ;clear screen
jmp L3 ;exit the search
L2:
add ebx,5 ;point to the next entry
loop L1 ;repeat until ECX = 0
L3:
jmp Menu ;run Menu again
Menu ENDP
;------------------------------------------------
enterInt PROC
;
; User input of n
; Receives: EAX = n
; Returns: EAX = n
;------------------------------------------------
mov edx, OFFSET msgInputN ;ask user to input n
call WriteString
call ReadInt ;int input by user
mov savedNum,eax
call Crlf
cmp eax, 0 ;is n less than 0
jl endTest
mov edx, OFFSET msgFact
call WriteString
call nonRecurFact ;EAX = factorial(n)
call WriteDec ;display factorial
call Crlf
call Crlf
call WaitMsg
ret
enterInt ENDP
;-------------------------------------------------------
Factorial PROC
;
; Calculates a factorial
; Receives: [ebp+8] = n, the number to calculate
; Returns: EAX = factorial of n
;--------------------------------------------------------
;(Fact.asm)
push ebp ;save stack base pointer
mov ebp, esp
mov eax, [ebp+8] ;get n
cmp eax, 0 ;is n < 0?
ja L1 ;yes: continue
mov eax, 1 ;no: return 1
jmp L2
L1:
dec eax
push eax ;Factorial(n-1)
call Factorial
;Instructions from this point on execute when each
;recursive call returns.
ReturnFact:
mov ebx, [ebp+8] ;get n
mul ebx ;edx:eax = eax * ebx
L2:
pop ebp ;return EAX
ret 4 ;clean up stack
Factorial ENDP
;------------------------------------------------
nonRecurFact PROC USES ECX EDX
;
; Calculates Nonrecursive Factorial
; Receives: EAX = n (as input by user)
; Returns: EAX = nonrecursive factorial
;------------------------------------------------
.IF eax == 0 || eax == 1 ;special cases
mov eax, 1 ;factorial == 1
jmp L2 ;quit procedure
.ELSEIF eax > 12 ;n is too large
mov edx, OFFSET msgError
call Crlf
call WriteString
jmp L2 ;quit procedure
.ENDIF
mov ecx, eax ;ecx = counter
L1:
dec ecx ;ecx = n - 1
mul ecx ;eax = n * (n - 1)
cmp ecx, 1 ;is counter > 1?
ja L1 ;true? then continue
L2:
ret
nonRecurFact ENDP
;------------------------------------------------
factCompare PROC
;
; Receives: Nothing
; Returns: Nothing
;------------------------------------------------
call enterInt
mov ecx, numOfTimes ;counter
call GetMseconds ;get miliseconds since midnight
mov startTime, eax ;save start time
L1:
push ecx ;save outer loop counter
mov ecx, numOfTimes ;counter inner loop
L2:
mov eax, savedNum
call nonRecurFact ;nonRecursive factorial
loop L2 ;next inner loop iteration
pop ecx ;restore outer loop
loop L1 ;inner loop
call GetMseconds ;get miliseconds since midnight
sub eax, startTime ;get running time
mov edx, OFFSET msgNonRec
call WriteString
call WriteDec ;display time
call Crlf
mov ecx, numOfTimes ;counter
call GetMseconds ;get miliseconds since midnight
mov startTime, eax ;save starting time
L3:
push ecx ;save outer loop counter
mov ecx, numOfTimes ;counter inner loop
L4:
push savedNum
call Factorial ;recursive factorial
loop L4 ;inner loop
pop ecx ;restore outer loop counter
loop L3
call GetMseconds ;get miliseconds since midnight
sub eax, startTime ;get running time
mov edx, OFFSET msgRec
call WriteString
call WriteDec ;display time
call Crlf
call Crlf
call WaitMsg
ret
factCompare ENDP
;------------------------------------------------
endTest PROC
;
; Receives: Nothing
; Returns: EDX = offset of message
; Sets CF = 1 to signal end of program
;------------------------------------------------
mov edx,OFFSET msgEnd ;msgEnd into edx
call WriteString ;display message
call Crlf ;endl
stc ;CF = 1
jc ExitProg ;if CF=1 then jump to Global ExitProg
endTest ENDP
END main
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.