I am struggling with the implementation in MIPS of detecting for overflow and throwing an error using addu.
This is for a school assignment. We were given code that was a very basic bank ledger. The ledger asks the user for input then if it is positive it adds to the balance and if it is negative it subtracts from the balance. I have already improved it to detect for non-integer inputs as per the assignment, and now I need to be able to detect for overflow and throw an error message and not change the balance if overflow is detected (then re-prompt for a transaction). I figured here since this is only addition, if the signs are the same and result in the opposite sign, then there is overflow. I also figure that if the signs are opposite then no overflow should happen.
Currently it seems to skip right over my overflow detection, so it works, but is not detecting overflow as I need for the assignment. Any advice on what I am doing wrong?
Here is the relevant part of my code:
loopB:
li $s1, 0 #### reset $s1
add $s1, $zero, $t3 #### load integer value into $s1
beqz $s1, done # If $s1 equals zero, branch to done
li $s2, 0 #### initialize $s2 for temporary balance
addu $s2, $s0, $t6 #### set temporary balance to initial balance
addu $s2, $s0, $s1 # add transaction amount to the temporary Balance
oTest:
sltiu $t6, $s0, 0 #### if $t6 == 1 then number is negative
sltiu $t7, $s1, 0 #### if $t7 == 1 then number is negative
bne $t6, $t7, LoopC #### if opposite signs then no overflow
sltiu $t8, $s2, 0 #### if $t8 == 1 then the number is negative
and $t9, $t6, $t7 #### if $t9 == 1 then $t6 and $t7 are both negative
bne $t9, $t8, over #### if $t9 and $t8 are not both negative, then overflow has occured
sgtu $t6, $s0, $zero #### if $t6 == 1 then number is positive
sgtu $t7, $s0, $zero #### if $t7 == 1 then number is positive
sgtu $t8, $s0, $zero #### if $t8 == 1 then number is positive
and $t9, $t6, $t7 #### if $t9 == 1 then $t6 and $t7 are both positive
bne $t9, $t8, over #### if $t8 and $t9 are not equal then overflow has occured
LoopC:
addu $s0, $s0, $s1 #### add transaction to balance
li $v0, 4 # system call code for print_string
la $a0, tabs # load address of tabs into $a0
syscall # used to space over to the Balance column
li $v0, 1 # system call code for print_integer
move $a0, $s0 # move Bank Balance value to $a0
syscall # print Bank Balance
b loop # branch to loop
over:
li $v0, 4 #### system call code for print_string
la $a0, oMsg #### load address of msg. into $a0
syscall #### print the string
li $s2, 0 #### reset $s2
li $v0, 1 #### system call code for print_integer
move $a0, $s0 #### move Bank Balance value to $a0
syscall #### print Bank Balance
b loop # branch to loop
Can you explain what you're trying to do here:
addu $s2, $s0, $t6 #### set temporary balance to initial balance
addu $s2, $s0, $s1 # add transaction amount to the temporary Balance
?
Those two instructions don't make sense together. The second wipes out / resets $s2
without using the result of the first.
You're using unsigned compare for less than with an immediate of 0 — that will always produce false, as no unsigned number is less than zero, by definition of unsigned numbers. In other words, negative is not a property that is possible for unsigned numbers.
If you want to know if the number is negative, use a signed compare instead.
FYI, you can also use shifting to extract or replicate the sign bit, so by using arithmetic shift of 31, getting either a -1 or a 0, and by using logical shift of 31 getting either a 1 or a 0.
Fundamentally, you're dealing with signed integers, so all your compare operations should be signed unless you really know something different somewhere there.
However, you are right that you need to do unsigned addition and/or subtraction in order to avoid the processor's automatic signed overflow detection, because if you hit that it will terminate your program. When there is no overflow, the unsigned addition will produce the same number, same numeric value, same bit pattern as the signed addition, so, this works. — and if there is overflow, you can detected it as you're thinking, e.g. after the addition.
But the comparisons need to be done with signed arithmetic in order to make sense, and, these signed compares (unlike signed addition/subtraction) don't risk hitting the processor's overflow trap.