MIPS instructions are 32 bits longs, and so are the addresses uses by a program.
This implies that the lw
instruction is unable to specify a full 32-bit address as an immediate.
Simply put, the instruction lw $t, var
is not valid (expect for very few cases).
In fact, its encoding is
lw $t, offset($s)
1000 11ss ssst tttt iiii iiii iiii iiii
Where the i bits show that only 16 bits are used to specify an address (and that a base register must always be specified, eventually the $zero
register can be used).
So the assembler does this trick: whenever you use a lw $t, var
it assembles that instruction into two instructions, one that load the upper 16 bits of the address into $at
and a lw
that use $at
as a base register with the lower 16 bits of the address as the offset.
lui $at, ADDR_H #ADDR_H is ADDR >> 16
lw $t, ADDR_L($at) #ADDR_L is ADDR & 0xffff
Note that since the lw
reads from $at
+ ADDR_L the final address used is ADDR_H << 16 + ADDR_L = ADDR. As expected.
There is subtlety here, pointed out by Mike Spivey (Many thanks to him), see below
This kind of instructions, that doesn't map directly into the ISA, are called pseudo-instruction.
The $at
register is reserved for the assembler exactly for implementing them.
In MARS you can disable the pseudo instructions by unchecking Settings > Permits extended (pseudo) instructions and format.
While programming without pseudo-instructions will grow annoying pretty quickly, it is worth doing at least once, to fully understand the MIPS architecture.
Mike Spivey correctly noted that the 16-bit offset immediate is sign-extended before being added to the base register.
This calls for a correction of the value I called ADDR_H
in case ADDR_L
turns out to be negative when interpreted as a 16-bit two's complement number.
If this turns out to be true, ADDR_H
must be incremented.
The general formula for ADDR_H
can be corrected to ADDR_H = ADDR >> 16 + ADDR[15]
where ADDR[15]
denotes the value of bit 15 of ADDR
(which is the sign bit of ADDR_L
.
0x10010000
happens to be the address ofx
. – Jester