Assembly Language Operations
Conditional Branches
Conditional branches are much more useful than unconditional branches. If a comparison operation gives a computer the ability to make a decision, conditional branches allow the computer to act on a decision.
In the ARM, conditional branches are executed (taken) or not according to the contents of the four condition codes of the Current Program Status Register (CPSR). For instance, the BNE (branch not equal) instruction refers to the Z bit flag in the CPSR. If the Z bit is set (i.e. some result was zero or a comparison was equal), then the branch is not taken. If the Z bit is clear (i.e. some result was non-zero or a comparison was not equal), then the branch will be taken.
Consider the following example code, which uses a BNE instruction to control a loop:
MOV | r0, #5 | ; use register r0 as a loop counter and initialize it to the value 5 | |
loop | ; label indicating the start of the loop | ||
... | ; various instructions that form the body of the loop | ||
... | ; and perform useful tasks | ||
SUB | r0, r0, #1 | ; decrement the loop counter by subtracting 1 from r0 | |
CMP | r0, #0 | ; perform a comparison between the value in r0 and zero | |
BNE | loop | ; if comparison was not equal, jump back to the loop | |
; label and repeat | |||
... | ; instructions after the end of the loop |
Remember that the CMP instruction does not issue a result; rather it tinkers with the condition code bits. The BNE instruction then inspects the Z bit to determine whether the branch should be taken or not. The above code will repeat the loop 5 times before the program can proceed to executing the instructions after the loop's end.
The same program can be rewritten by using the "S" suffix version of the SUB instruction, namely SUBS.
MOV | r0, #5 | ; use register r0 as a loop counter and initialize it to the value 5 | |
loop | ; label indicating the start of the loop | ||
... | ; various instructions that form the body of the loop | ||
... | ; and perform useful tasks | ||
SUBS | r0, r0, #1 | ; decrement the loop counter by subtracting 1 from r0 | |
; and set the condition code bits based on the subtraction | |||
; result | |||
BNE | loop | ; if the Z bit is clear (i.e. "0"), jump back to the loop | |
; label and repeat | |||
... | ; instructions after the end of the loop |