Homework 5
|
Modified: |
The assignment provides practice using pass-by-value parameters on the stack and checking for computation errors, due in this case to overflow during multiplication.
Design an algorithm as a function to perform integer exponentiation. The inputs to the function should be a signed base and an unsigned exponent. The result of the function should be the base raised to the exponent, for example for base=-4 and exponent=3, then -43 would result in -64.The inputs to the function should be the 32-bit signed base and the 32-bit unsigned exponent. The 32-bit signed function result is returned in the eAx register. Additionally, the overflow flag serves as an overflow indicator to indicate that an overflow beyond 32-bits has occurred. The exponentiation function must save and restore all registers and flags except eAx and flags.
Hints and Warnings :
- Cover Page - Your name, date, and Homework 5. Staple all pages together.
- Assembler program listing (e.g. main.lst).
- Output - Use test input of: -43, -20, 230, 231, -231 and 43.
A possible pseudo code
- Remember that ReadInt and ReadDec alters the eAx register.
- Use only registers and the stack in the Exponent function, no global variables.
- Do not save and restore eAx or the flags!
- Use 32-bit signed multiplication (e.g. eAx*eCx) which produces a 64-bit signed result in eDx:eAx. Remember that as only a 32-bit result can be returned, the result cannot extend into eDx. Recall that when the multiplication extends into 64 bits, the overflow and carry flags are set.
- An overflow should be tested for after multiplication using the JO or JC conditional branching instruction or the .IF OVERFLOW? operation. When overflow occurs, the result in eAx alone is wrong, since the answer includes eDx.
- Test the value of the overflow in your calling function to determine whether to print the eAx register as a valid result or print an error message.
INCLUDE Irvine32.inc
.data
Error db 'Error...Cannot compute N!',0
Prompt db 'Enter unsigned number:',0
.code
Main Proc Near
; cout << "Enter number:";
Lea eDx, Prompt
Call WriteString ; cin >> eAx;
Call ReadDec
Push eAx
Call Factorial ; eAx = Factorial(eAx)
.IF OVERFLOW? ; if (Overflow)
Lea eDx, Error ; cout << Error;
Call WriteString
.ELSE ; else cout << eAx
Call WriteDec
.ENDIF
Push 0 ; Stop
Call ExitProcess
Main Endp
|
;; int Factorial (int N);
;; - Calculate N!
;; Parameters - N positive integer value
;; Returns - eAx factorial value on return
;; Registers Altered - eAx and Flags
Factorial Proc Near ;; int Factorial(int N)
Push eBp
Mov eBp, eSp
Push eDx ;; Save registers
Push eBx ;;
Mov eBx, [eBp+8]
Mov eAx, 1 ;; eAx := 1
Fora: Cmp eBx, 1 ;; for(eBx=N; eBx>1; eBx--) {
Ja Doa ;; eAx = eAx * eBx;
Jmp EndFora ;; if( Overflow ) break;
Doa: ;; }
Mul eBx
.IF OVERFLOW?
Jmp Break
.ENDIF
Dec eBx
Jmp Fora
EndFora:
Break:
Pop eBx ;;
Pop eDx ;; Restore registers
Mov eSp, eBp
Pop eBp
Ret
Factorial Endp
End Main
|