SemperCallide
SemperCallide

Reputation: 2070

Machine code for branching

I'm a little confused as to how a branching instruction translates to machine code. I read in my book that the branch if equal instruction is a B-Type instruction, which is formatted like so:

opcode reg1 reg2 address + offset 6 5 5 16

In my textbook, there is a problem where I am shown a program, which I'm told is loaded at 0x4321ABC8 and looks like this:

L1:   sw   $t0,3000($t1)

  addi $s1,$t1,-6

  beq  $t0,$t1,L1

As you can see, the 3rd line of code is branch if equal.

I am trying to convert this program into binary (or hex). On the branch if equal instruction, I don't understand exactly what it is I'm supposed to enter into the address + offset field.

First I thought the answer would be...

base address (0x4321ABC8), plus 4 times the number of instructions from base which is where the program counter would be (4 * 2 = 8),
Then minus four for the offset, which would be the original base address, 0x4321ABC8.

The problem with this is that 0x4321ABC8 is a number too big to fit into the 16 bit offset space of the instruction.

So then I thought that the answer would be to ONLY include the offset (which would be -8), however if that were the case, I don't know why the problem in the book would bother to tell me that the program is loaded at 0x4321ABC8.

Any help would be greatly appreciated!

Upvotes: 0

Views: 2463

Answers (1)

Jester
Jester

Reputation: 58762

The offset is in fact encoded as number of words (or instructions, if you like), so you don't need to multiply by the word size (4 bytes). Also, this offset is relative to the already-updated PC, that is the address of the following instruction. So, your offset is -3.

That isn't the whole story though. MIPS does have branch delay slots but they are normally hidden from the programmer. The assembler may try to fill these if it can do so without changing the meaning of your code. If you feed your example into a real-world assembler (in this case, gas) it will move the addi $s1,$t1,-6 into the delay slot of the branch because the result of that instruction is not used in the condition:

00000000 <L1>:
   0:   ad280bb8        sw      t0,3000(t1)
   4:   1109fffe        beq     t0,t1,0 <L1>
   8:   2131fffa        addi    s1,t1,-6

In this swapped order, the encoded offset is -2, as you can also see from the fffe value.

PS: If you are using SPIM be aware it has known off-by-one problem with offset encoding. That is it uses the address of the current instruction instead of the next.

PS #2: Just because they give you some extra information, it doesn't mean you have to use it. That's a common trick to confuse poor students ;)

Upvotes: 3

Related Questions