Homework 5
Arithmetic and Pass-by-value

Modified

Overview

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.

Assignment

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.

Turn in

  1. Cover Page - Your name, date, and Homework 5. Staple all pages together.
  2. Assembler program listing (e.g. main.lst).
  3. Output - Use test input of: -43, -20,  230, 231, -231 and 43.
Hints and Warnings :
  1. Remember that ReadInt and ReadDec alters the eAx register.
  2. Use only registers and the stack in the Exponent function, no global variables.
  3. Do not save and restore eAx or the flags!
  4. 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.
  5. 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.
  6. 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.
A possible pseudo code

Overflow Checking Example

 
Overflow Checking - Factorial Function
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