Real Branches
Let's do a couple of examples of real branches in this bit of code:
.text
bne $20 $21 forth
add $10 $11 $12 #<- PC is here when executing the bne
add $10 $11 $12
back: add $10 $11 $12 # here is -9 instructions from the beq PC
add $10 $11 $12
add $10 $11 $12
add $10 $11 $12
add $10 $11 $12
add $10 $11 $12
forth: add $10 $11 $12 # here is 8 instructions from the bne PC
add $10 $11 $12
beq $5 $6 back
add $10 $11 $12 #<- PC is here when executing the beq
- Let's do the forward branch first
- Start at the instruction following the branch
- Count instructions in the forward direction until we reach the branch's target
- In this case, we get 8
- The opcode for bne is 5, so we can box up this instruction, taking the times-4 trick into account,
and we get this
- Now let's do the backward branch; it's the same as before except that the count will be negative
- Start at the instruction following the branch
- Count instructions in the backward direction until we reach the branch's target
- In this case, we get -9
- The opcode for beq is 4, so we can box up this instruction, taking the times-4 trick into account,
and we get this
Copy this code and paste it into MARS to confirm that we have right answers here
The assembler gets the same result, but of course, it can't count instructions the way we do.
Instead, it will subtract the PC value from the address of the branch target.
This will give it the byte offset,
so it will divide that by 4 to get the word offset.
Let's do one of them that way by hand:
- Look up "forth" in the Labels window in MARS; it's 0x00400024
- Now find the bne instruction in the Text Segment window; it's at 0x00400000
- The next instruction after the bne is at 0x00400004;
this is what will be in the PC while the CPU is executing the branch
- 0x00400024 - 0x00400004 = 0x00000020 = 32 decimal
- 32 / 4 = 8, the same value we got by counting
SEE HOW EASY THIS IS?
There is a caveat that goes with this:
- There are fake instructions that the assembler replaces with real instructions
- Sometimes the replacements are more than one instruction
- If there are any of those between the branch instruction and its target, they will mess up your count
- This is not a problem for the assembler because it does the replacement of the fake instructions
before it generates the machine code
- This will not be a problem for you either because I would never be so mean as to put such
instructions in code that you have to count
- But you still need to know about it