For making a reference to a memory using 32-bit register and an offset a 32-bit, lw or sw cannot use to achive this. The main reason of this is MIPS instruction formats cannot support 32 bit constants. Therefore an arbitrary 32-bit immediate constant cannot load into a register in a single instruction without performing a data load from memory. By using 16-bit Thumb instructions, the range of constants generated is much smaller and so the task could not be perform.
Immediate implies the constant is part of the instruction.
This is the part where lui (load upper immediate) function. The instruction looks like:
lui $rt, immed
This is an I-type instruction. $rs is ignored. It can have any value.
Instruction | B31-26 | B25-21 | B20-16 | B15-0 |
opcode | register s | register t | immediate | |
lui $rt, immed | 001 111 | ignored | - | immed |
The dashes are 5-bit encoding of the register number in UB. Example, $r7 is encoded as 00111. The offset is represented in 16-bit 2C.
For lui function, it direct copies its 16-bit immediate operand to the upper two bytes of the designated register. Therefore the lower 16 bit is all 0's.
Suppose we want to load a 32-bit word into register, as already say MIPS only supports 16-bit constants. Therefore there is a trick to achieve it. First is to load the higher-order bits using the lui instruction
lui $t0, 10101010101010101010
which it will loads the constant (2nd operand) into the upper two bytes (significant 16 bits) of $t0. For the remainder of the lower order bits, it can be load using the ori (or-immediate) instruction.
ori $t0, $t0, 10101010101010101010
In diagram:
Another way is using addi.
lui $r1, 0x0123
addi $r1, $r1, 0xabcd
This is not recommended to use because it has problem, which is when the immediate value is negative, it will make the upper 16 bits all be 1's, and that time using addi will ruin the upper 16 bits.
Therefore it is better to use ori more than addi.
Using $at
The pseudo instruction, li $rt, immed loads an immediate value to a register, and this can be a 32 bit value. The instruction is translated to:
lui $at, 0x0123 ori $at, $at, 0xabcd
$at is actually register $r1. This register is used for translating pseudoinstructions to real instructions. If wants to avoid clobbering other registers during translation, $at is reserved specifically for this purpose.The assembler must represent immediate value as a 32 bit 2C binary number if the immediate value is written in base 10, then need to split the high 16 bits for the lui instruction and the low 16 bits for the ori instruction.
By SOON BOON JIAN
B031210199