The unconditional branch instruction allows us to skip to a new location to continue executing code from. When the branch executes, the program counter is not increased by 4 bytes as normal, but instead its value is replaced with the address of a new instruction.
Branch. Change the program counter to the address of the line identified by label.
In this code sample, line number 3 has a branch that will cause execution to skip over the code on lines 4 and 5 and execute the next line
after the label
target, which is line 7.
1 2 3 4 5 6 7
MOV r1, #1 @random work MOV r2, #2 B target @branch to target MOV r3, #3 @skipped MOV r4, #4 @skipped target: MOV r5, #5
The assembler calculates the destination address and stores it in the instruction as +/- value to add to the
PC register when the branch executes.
This offset is stored as 24-bits in the instruction:
Since instruction addresses in ARM are always multiples of 4, the last two bits of any instruction address are always 00. This fact is used to compress the stored offsets - the value stored in the instruction has been right shifted 2 bits to remove those 0s. To use the stored address, the hardware first shifts it to the left 2 bits and then sign extends it. For example, in the code sample above, the instruction looks like:
If we mask the last 24 bits and then shift them left 2 and sign extend, we get:
The final offset value is 4. To that value, we have to add 8. (This add 8 is due to the historical design of the ARM architecture where the
PC will already have advanced 2 instructions or 8 bytes before the branch address is actually used). So the final amount for the branch is 12 bytes, or
at 4 bytes per instructions, 3 instructions ahead. Sure enough, the shown branch skips over 2 instructions and runs the third one after the