Overview
A branch is an instruction that allows us to change the sequence of instructions executed. Branches allow us to bypass one sequence of instructions and execute a different sequence of instructions. The branch instruction results in the PC (Program Counter) being loaded with the the address of the instruction that is going to be executed. You can indicate where the application will branch to by providing a label.
Labels
A label in ARM assembly is simply a name given to to the address of an instruction. A label can be any string that starts with a non-numeric value at the start of a line. Make sure there are no spaces that proceed a label. Labels are useful because the software developer does not need to know the exact address of the instruction they want to branch to, instead they can simply branch to the label where the desired instruction is located at.
SUB R0, R0, #1 B SKIP_ADD ADD R0, R0, #1 SKIP_ADD AND R0, R0, 0xFF
In the Cortex-M4 architecture, the branch (B) instruction allows the user to branch to an instruction that is within -16MBs to +16MBs of the current instruction. If you need to branch farther than 16MBs, there is a BX ( indirect branch) that will allow you to branch to any address in the Cortex-M memory map. This instruction requires that the address first be loaded into a general purpose register.
LDR R0, =(LABEL_TO_BRANCH) ; Load the address into R0 BX R0 ; Execute the indirect branch
A Branch instruction can be made conditional by adding a condition code just as you would an ALU instruction. Be aware that when you add a condition code on to the branch instruction (B), the range you are allowed to branch to is reduced to -1MB to +1MB of the current current instruction. The table below summarizes the effective ranges of B and BX instructions. We will cover BL and BLX later.
Cortex-M4 Device Generic User Guide, Pg 3-119
Examples
The following examples compare how a high level language control structure can be mapped into an equivalent ARM assembly instructions.
for loop
C Code
a = 0; for(i = 10; i > 0; i--) { a += i; }
ARM Assembly
MOV R0, #0 MOV R1, #10 START_FOR CMP R1, #0 BLE END_FOR ADD R0, R0, R1 SUB R1, R1, #1 B START_FOR END_FOR
while loop
C Code
i = 0x90 // Loop until Bit 7 and Bit 1 are 1 while( (i & 0x81) != 0x81) { i--; }
ARM Assembly
MOV R0, #0x90 WHILE_START TST R0, #0x80 TSTNE R0, #0x01 BNE WHILE_DONE SUB R0, R0, #1 B WHILE_START WHILE_DONE