Why do MIPS operations on unsigned numbers give signed results?

dankilman picture dankilman · Dec 29, 2009 · Viewed 10.7k times · Source

When I try working on unsigned integers in MIPS, the result of every operation I do remains signed (that is, the integers are all in 2's complement), even though every operation I perform is an unsigned one: addu, multu and so fourth...

When I print numbers in the range [2^31, 2^32 - 1] I get their 'overflowed' negative value as if they were signed (I guess they are).

Though, when I try something like this:

li $v0, 1
li $a0, 2147483648                # or any bigger number
syscall

the printed number is always 2147483647 (2^31 - 1)

I'm confused... What am I missing?

PS : I haven't included my code as it isn't very readable (such is assembly code) and putting aside this problem, seems to be working fine. If anyone feels it is necessary I shall include it right away!

Answer

Pedro Silva picture Pedro Silva · Dec 29, 2009

From Wikipedia:

The MIPS32 Instruction Set states that the word unsigned as part of Add and Subtract instructions, is a misnomer. The difference between signed and unsigned versions of commands is not a sign extension (or lack thereof) of the operands, but controls whether a trap is executed on overflow (e.g. Add) or an overflow is ignored (Add unsigned). An immediate operand CONST to these instructions is always sign-extended.

From the MIPS Instruction Reference:

ALL arithmetic immediate values are sign-extended [...] The only difference between signed and unsigned instructions is that signed instructions can generate an overflow exception and unsigned instructions can not.