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