I had a question about unsigned and signed numbers in the MIPS Assembly Language, specifically for the add instruction.
On here: https://inst.eecs.berkeley.edu/~cs61c/resources/MIPS_Green_Sheet.pdf, the addu instruction is said to be add unsigned, for example. I know that this name is supposed to be a misnomer in MIPS, as the U in ADDU actually means that the instruction does not check overflow (uncheck overflow), not that it deals exclusively with “unsigned” numbers.
According to this site: https://mathcs.holycross.edu/~csci226/MIPS/MIPS_InstructionReference.html
"After that, they are handled as signed or unsigned 32 bit numbers, depending upon the instruction. The only difference between signed and unsigned instructions is that signed instructions can generate an overflow exception and unsigned instructions can not."
My question is, which of the add instruction variants - add, addi, addiu, addu - deal with unsigned numbers (positive numbers)? And which of these numbers deal with signed numbers (positive AND negative numbers)?
And I am also confused about LBU vs LHU. I read somewhere that Load Byte is no sign extension and LHU is Load Half Word (no sign extension). What is that about? And which of the two deals with signed numbers?
My question is, which of the add instruction variants - add, addi, addiu, addu - deal with unsigned numbers (positive numbers)? And which of these numbers deal with signed numbers (positive AND negative numbers)?
As you already know, the add
and addi
forms will trap on signed overflow.
Thus, those forms are inappropriate for use on unsigned numbers in the general case, and only appropriate for unsigned if you know that they will stay in small number range (e.g. sums less than 2^31).
The addu
and addiu
forms will not trap on signed or unsigned overflow, and thus, these are appropriate for general use with both signed and unsigned numbers (except when overflow could happen, in which case they may be part of the solution but insufficient).
The lb
vs. lbu
forms sign extend vs. zero extending. If your 8-bit data is signed then use lb
to keep the same numeric values (across the whole 8-bit signed range) when extended to 32 bits; if your 8-bit data is unsigned, then use lbu
to keep the same numeric value when extended to 32 bits. If you never use 8 bit data (smaller than zero and) larger than 2^7 (127) then you can use either with impunity.
Once the value has been either sign-extended or zero-extended into the target register, the processor holds the bit pattern in that register, but does not remember whether or not the data type is signed or unsigned, so it is still up to the subsequence instruction stream (i.e. the machine code program) to treat the data appropriately.