Translating Mips assembly to machine code: BNE

0

Given this code:

[0x00000000]  arraycopy: lw $t0, 0($a0)
[0x00000004]             addi $a0, $a0,4
[0x00000008]             addi $a1, $a1,4
[0x0000000C]             sw $t0, -4($a1)
[0x00000010]             bne $t0,$0,arraycopy
[0x00000014]             Nop ( means no operation )

Now I'm interested to translate the bne command line to machine code:

What I got: 0001 0100 0000 1000 - ....

Now what will be the rest of the command?

**Update: I keep getting that the Offset value is: 1111 1111 1110 1100 which is -20 But the correct answer should be : 0xfffb which is -5

Any Idea why?**

assembly
mips
machine-code
asked on Stack Overflow May 12, 2016 by sijaan hallak • edited May 13, 2016 by Seva Alekseyev

1 Answer

1

Because MIPS instructions must be aligned to 4 byte boundaries, the offset within a branch instruction can be encoded [and is encoded] as a word offset and not a byte offset. This increases the reachable range of the branch by 4x [a good thing]. So, for an signed encoded offset of 16 bits, you get a signed byte offset of 18 bits

Thus, for a given byte offset, it is encoded in the branch by shifting it right by 2 [i.e. the lower two bits must always be zero, so nothing gets lost]. When the instruction is executed, the hardware will take the offset and restore it to a byte offset by shifting it left by 2.

The byte offset is calculated not from the address of the branch itself (0x00000010) but from the address of the instruction following (0x00000014).

So, the byte offset is -0x00000014 (decimal -20) --> 0xFFFFFFEC. Shifting this right 2 bits [dividing by 4] produces 0xFFFFFFFB (decimal -5).

Since the encoded offset is only a signed 16 bits, we end up with 0xFFFB

answered on Stack Overflow May 12, 2016 by Craig Estey • edited May 12, 2016 by Craig Estey

User contributions licensed under CC BY-SA 3.0