From ARMwiki
Jump to: navigation, search
B / BL
Instruction B / BL-
Function Branch (/ with Link)
Category Branch
ARM family All
Notes -


B / BL : Branch / Branch with Link

B(ranch) and B(ranch with )L(ink) cause the program counter to point to a new address, thus the program continues at the instruction thus pointed to.

A B (Branch) is a jump, and is roughly equivalent to the JMP instruction on processors such as the 6502 and the x86 family (though due to the use of conditional execution, this one instruction can replace numerous jump instructions on CISC processors).

A BL (Branch with Link) is a jump that additionally writes a return address to R14. This allows for a gosub/return mechanism, akin to RTS on the 6502 or CALL on the x86.

The only parameter is a signed 24 bit integer which is shifted two places to the left, thus meaning a signed 26 bit value where the two least significant bits are zero; therefore allowing branches to +/- 32 MiB range.


  B[L]  <address>


  PC = address


  B    &8          ; Branch to address +8 (SWI vector!)
  BL   writeline   ; Branch with link to "writeline" function

Details and comparisons

As said above, BL provides a gosub/return mechanism. It works by placing the return address into R14 (also known as LR for Link Register).
Returning from the function is achieved simply by writing the contents of R14 back into the Program Counter. This can be achieved by simply performing MOV PC, R14, or specifying PC instead of R14 in a multiple register load (if you saved R14).

Be aware that every BL will corrupt R14, so you should preserve your copy on the stack if you will be calling another function.

Here is a very simple example of an ARM function:

    BL     my_func
    B      somewhere_else
    ...some code here...
    MOV    PC, R14

In this example, the code flow is entry -> my_func -> entry+1 -> somewhere_else.

The same idea in 6502 would be:

    JSR my_func
    JMP somewhere_else
    ...some code...

and in x86 code:

    call  my_func
    jmp   somewhere_else
    ...some code...

Please note that due to how the ARM works, the effective offset is the difference between the current instruction plus eight and the branch target. This is because when the branch is to be executed, PC is two instructions (thus eight bytes) further on.

Thus, for example, if you were to encounter an ARM assembly BNE instruction like this:

address codeword     opcode  operand
0x0024  1A00002E     BNE     loc_00E4

You would need to perform the following mental calculation to get the correct branch address (E4) from the codeword 2E.

2E * (4 bytes/word) + 8 bytes (PC is 2 instructions in advance) = B8 + 8 = C0

Thus C0 + 24 = E4.


The instruction bit pattern is as follows:

31 - 28 27 26 25 24 23 - 0
condition 1 0 1 L signed immediate 24 bit

The L flag specifies if this is a B or BL.

Personal tools