I am confused about the difference between add and addu.
The MIPS instruction reference says:
- add (with overflow)
- add unsigned (no overflow)
My understanding is to use add with signed operands and addu with unsigned operands.
But let's consider this example (with only 6bit):
overflow | V 1 | 1 1 1 <- carry | 1 1 1 1 0 1 + | 1 1 1 1 1 0 = ----------------- | 1 1 1 0 1 1
And this is my reasoning:
- if I consider the first and second operand signed numbers (two's complement), then the result is correct (-3 + -2 = -5) and I don't want an overflow exception. So I would use addu to avoid this exception, but, although the result is the same, the name suggests to use addu is for unsigned numbers!
- if I consider the first and second operand unsigned numbers, then I want an exception to be raised (because 61 + 62 is not equal to 59). So I would use add to raise the exception, and not addu, as the name would suggest to do.
Now my questions are:
- assuming that operands are signed (negative in the example above) numbers, should I use addu (as my reasoning suggests) or I should use add (as the name suggests)?
- assuming that operands are unsigned (positive) numbers, should I use add (as my reasoning suggests) or addu (as the name suggests)?
The instruction names are misleading. Use addu
for both signed and unsigned operands, if you do not want a trap on overflow.
Use add
if you need a trap on overflow for some reason. Most languages do not want a trap on signed overflow, so add
is rarely useful.
If you are using signed numbers, you should use add
if you want a trap to be generated when the result overflows.
If you are using unsigned numbers, you should always use addu
and check the overflow of the addition by comparing the result with either numbers (if the result is less than the operands then the addition did overflow).
Here goes a snippet to show how you would check for overflow in unsigned addition:
li $a1, 0xFFFF0FFF
li $a2, 0x00010000
addu $a3, $a1, $a2 # This unsigned addition overflows (set $a3 to $a1+$a2)
bgt $a1, $a3, overflowed
bgt $a1, $a2, overflowed
# If you get here, unsigned addition did not overflow
# your code goes here...
overflowed:
# If you get here, unsigned addition overflowed
# your code goes here...
OVERFLOW is NOT as declared in the question, this carry bit is NOT an overflow bit, in the given example there is NO OVERFLOW, overflow is when:
MSB1 = 1 && MSB2 = 1 && MSBofRESULT = 0
OR
MSB1 = 0 && MSB2 = 0 && MSBofRESULT = 1
so stick with add
it will flag overflow, and the carry bit in your example (which is not an overflow) will not bother you. addu
does the same except no exception is ever raised.
Basically both opcodes are signed addition. So in MIPS they uses 31 bits to store data, maximum number is (2 raise to 31)-1 and 1 bit is reserved to store the sign for the numbers. As delineated above,The basic difference between "add" & "addu" is that the former throws an exception when the result number is greater than the maximum number than 31 bit occupy. The latter one executes without showing any warning.
Eg, 3 bit addition maximum num = (2**(n-1))-1 minumem num = -(2**(n-1)) so in our case max = 3 and min = -4
li $t1,3
li $t2,1
add $t3,$t1,$t2 -----> throws an arthimetic overflow exception
addu $t3,$t1,$t2 ------> t3 = -4
that is it.
It's actually not an overflow in your example. An overflow occurs when the carry into the sign bit does not equal to the carry out of the sign bit. In your example, although the carry out of the sign bit is "1" (the seemingly overflow), the carry into sign bit is also "1". Therefore, in this condition MIPS will not consider it as an overflow. The pattern of how overflow occurs is actually corresponding to whether the result is correct. That is, if the result is outside of the range your bits can represent, an overflow occurs. For example, if you add two 4-bit numbers 0111 (7) and 0010 (2) together, you get an overflow since the result (9) is outside of the range a 4-bit number can represent (-8 to 7). If you look at the arithmetic:
0111 (7) + 0010 (2) = 1001 (-7)
you can see that although there's no carry out of the sign bit, the result is still incorrect. Therefore this is an overflow (and MIPS will detect it).
来源:https://stackoverflow.com/questions/16634110/difference-between-add-and-addu