|Instruction||B / BL-|
|Function||Branch (/ with Link)|
B / BL
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 (thus allowing branches to +/- 32 MiB range).
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 .my_func ...some code here... MOV PC, R14 .somewhere_else
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 .my_func ...some code... RTS .somewhere_else
and in x86 code:
call my_func jmp somewhere_else my_func: ...some code... ret somewhere_else:
The instruction bit pattern is as follows:
|31 - 28||27||26||25||24||23 - 0|
|condition||1||0||1||L||signed immediate 24 bit|