Branch in MIPS works with offsets (shifted left 2 positions), not absolute addresses.
BNE -- Branch on not equal
Description:
Branches if the two registers are not equal
Operation:
if $s != $t advance_pc (offset << 2)); else advance_pc (4);
Syntax:
bne $s, $t, offset
Encoding:
0001 01ss ssst tttt iiii iiii iiii iiii
So it's Loop
offset from the BNE
instruction that should go on the i
part, not its absolute address.
EDIT: with edited question code:
Loop:
addu $a0, $0, $t0
ori $v0, $0, 4
syscall
addi $t0, $t0, -1
bnez $t0, Loop
Since all MIPS instructions are 32-bit wide (4 bytes), we can calculate offset easily:
Loop
address is -4 instructions from BNEZ instruction, so it's -4 x 4 = -16 bytes away.- But we need to add one more word because in MIPS PC was already incremented by 4 and when BNEZ is executing, PC is already pointing to next instruction (see delay slot in MIPS). So final offset is -20 = -(0x14) = 0xFFFEC.
- We shift right 2 positions (divide by 4) to get this offset in words (instead of bytes): 0xFFFEC >> 2 = 0xFFFB
You can also do it by counting by words directly:
Loop
address is -4 instructions from BNEZ instruction- Additional -1 because PC already incremented: -5
- -5 = -(0x5) = 0xFFFB
So we got 0xFFFB for i
part; so whole instruction is 0x1500FFFB
.
By the way you can check this with any MIPS assembler or simulator.
(Screenshot from MARS simulator)