################################### # Integer multiplication using multiple adds # Sample solution Homework 7 ################################### .data MES0: .asciiz "Input control integer (0-halt, or 1-multiply): " MES1: .asciiz "ERROR, illegal input = " MES2: .asciiz "Input first integer: " MES3: .asciiz "Input second integer: " MES4: .asciiz "GOODBYE\n" MES5: .asciiz "UNDERFLOW, MIN = " MES6: .asciiz "GOODBYE\n" MES7: .asciiz " times " MES8: .asciiz " = " MES9: .asciiz "ERROR " MES10: .asciiz " too small\n" MES11: .asciiz " too large\n" NL1: .asciiz "\n" NL2: .asciiz "\n\n" MAXMES: .asciiz "OVERFLOW, MAX = " MINMES: .asciiz "UNDERFLOW, MIN = " MAX: .word 2147483647 # What is really needed here is the maximum positive integer in MIPS - you figure that out MIN: .word -2147483648 # What is really needed here is the minimum integer in MIPS - you figure that out .text main: li $v0,4 la $a0,MES0 syscall agn: li $v0,5 syscall # get the control integer andi $t0,$v0,0xfffffffe # mask the first bit beq $t0,$zero,ControlOK # If $t0 <>0 then the input was not 0 or 1 move $t0,$v0 # input not 0 or 1 li $v0,4 la $a0,MES1 syscall li $v0,1 move $a0,$t0 syscall li $v0,4 la $a0,NL2 syscall b main ControlOK: # control ($v0) is 0 or 1 bne $v0,$zero,Multiply li $v0,4 # GOODBYE message la $a0,MES4 syscall li $v0,10 # Halt syscall ################################ # Now we want to read in the two integers and multiply them # Multiply: li $v0,4 la $a0,MES2 syscall li $v0,5 syscall move $t0,$v0 # $t0 = first integer = A move $t6,$t0 # Holder for A li $v0,4 la $a0,MES3 syscall li $v0,5 syscall move $t1,$v0 # $t1 = second integer = B move $t7,$t1 # Holder for B bge $t0,$zero,Aplus # If first integer (A) is +, then add second (B) to 0 A times blt $t1,$zero,BothNeg # If second integer (B) is -, then both are minus # Since we now know A is negative and B is positive, we will simply swap them move $t0,$t7 move $t1,$t6 Aplus: li $t2,0 # $t2 will contain the 32-bit product aovr: ble $t0,$zero,OutRes addu $t2,$t2,$t1 xor $t3,$t2,$t1 blt $t3,$zero,OverFlow # if bit 31 of $t3=1, we have overflow addi $t0,$t0,-1 b aovr OutRes: li $v0,1 move $a0,$t6 syscall li $v0,4 la $a0,MES7 syscall li $v0,1 move $a0,$t7 syscall li $v0,4 la $a0,MES8 syscall li $v0,1 move $a0,$t2 syscall li $v0,4 la $a0,NL2 syscall b main OverFlow: li $v0,4 la $a0,MES9 syscall li $v0,1 move $a0,$t6 syscall li $v0,4 la $a0,MES7 syscall li $v0,1 move $a0,$t7 syscall # we output here one of two messages too small or too large # if one of the numbers is negative and the other is positive, # then the message is too small, else # it's too large. xor $t5,$t6,$t7 blt $t5,$zero,TooSmall li $v0,4 la $a0,MES11 syscall b main TooSmall: li $v0,4 la $a0,MES10 syscall b main ##################################### # Since both are negative, we have to proceed carefully # We test the two values and if either is max negative, the product will # be too large. If neither of the numbers is max negative, then change them to positive # and go back to compute like both positive # The test for max negative is done by masking the sign bit to 0 # and leaving the others unchanced. If the other bits are <>0 then it's # not at max negative BothNeg: andi $t4,$t6,0x7fffffff # mask out the sign bit of A beq $zero,$t4,OverFlow andi $t4,$t7,0x7fffffff # mask out the sign bit of B bne $zero,$t4,NoMax # neg $t7,$t7 b OverFlow # Neither is max negative so just set to positive and multiply NoMax: neg $t0,$t6 neg $t1,$t7 b Aplus