I am taking an architecture course currently and as part of that class I am learning MIPS assembly.
It is my understanding that the lw and sw operations are I-format instructions allowing 2 register operands, and one immediate operand:
[opcode] 6-bits, [rs] 5-bits, [rt] 5-bits, [immediate] 16-bits written as: lw $rt, offset($rs) # where offset is an immediate value
OK, so let's say I want to access A[i]. Assuming the base address of A is in register $s7 and the index (i) is in register $s1, I would have to do something along the lines of:
sll $t0, $s1, 2 # i*4 (offset) add $t0, $s7, $t0 # $t0 = &A[i] lw $t1, 0($t0) # $t1 = A[i]
What I'm confused about is my professor keeps saying that we can also do a lw instruction like this with 3 registers:
sll $t0, $s1, 2 # i*4 (offset) lw $t1, $t0($s7) # $t1 = A[i]
Are both of these solutions correct? Or is my instructor incorrect? You can't use a register for the offset can you? I thought the offset had to be an immediate number. It was my understanding that the reason you have to do the extra add instruction in the first solution, is actually because you cannot use a register as the offset.
The offset for lw
/sw
must be an immediate. If your instructor claims that there's a variant of lw
/sw
in the MIPS instruction set that accepts register offsets then he/she is incorrect.
However, there might be assemblers that accept such a variant as a pseudo-instruction, and translates it into actual MIPS instructions. In this case, a possible translation might be:
addu $at,$s7,$t0
lw $t1, 0($at)