Home | Projects | Notes > Computer Architecture & Organization > ARM Instruction Set Architecture (ISA) - Flow Control Instructions
The Program Counter (PC) gets updated to the memory address pointed to by the label, unconditionally.
xxxxxxxxxx
31 B Label @ Branch to 'Label'
2
3Label:
This instruction is necessary because there is no structured programming when it comes to assembly.
Conditional branch is the real power of the modern computers. It alters the path of the code based on values.
Because assembly does not support if...else statement, the programmer typically writes the program in pseudo-code in a structured manner, then translates it into the conditional branching that is supported.
xxxxxxxxxx
141/* if x > y then x = x + 1 else y = y + 1 */
2
3 cmp r1, r2 @ RTL: [r1] - [r2] (r1 is x and r2 is y)
4 bgt then @ Branch to 'then' if r1 is greater than r2.
5
6else:
7 add r2, r2 #1 @ else part
8 b exit @ Branch to 'exit'. Don't forget this!
9
10then:
11 add r1, r1 #1 @ then part
12
13exit:
14 @ exit instruction
Conditional branches test the bits in the CCR.
Condition codes that can be attached to branch to form conditional branches:
xxxxxxxxxx
221Encoding Mnemonic Branch on Flag Status Execute on Condition
2======== ======== ================================ =======================
30000 EQ Z set Equal (zero)
40001 NE Z clear Not Equal (not zero)
50010 CS C set Unsigned higher or same
60011 CC C clear Unsigned lower
70100 MI N set Negative
80101 PL N clear Positive or zero
90110 VS V set Overflow
100111 VC V clear No overflow
111000 HI C set and Z clear Unsigned higher
121001 LS C clear or Z set Unsigned lower or same
131010 GE N set and V set, or Greater or equal
14 N clear and V clear
151011 LT N set and V clear, or Less than
16 N clear and v set
171100 GT Z clear, and either N set and Greater than
18 V set, or N clear and V clear
191101 LE Z set, or N set and V clear, or Less than or equal
20 N clear and V set
211110 AL Always (default)
221111 NV Never (reserved)
Be aware that branches can take into account the signed or unsigned comparisons. Be careful when using the unsigned branches!!!
xxxxxxxxxx
41 | A = 0110 1100 | B = 1110 1100
2--------------------+-------------------------------
3Unsigned comparison | A < B
4Signed comparison | A > B
These condition codes can be used with non-branch instructions as well.
ARM has four compare and test instructions; TEQ
, TST
, CMP
, CMN
.
All of these set the CCR flags by default, so an "
S
" does not have to be added to these instructions.
Even if you do add it, assembler won't complain.
TEQ
(Test Equivalence)
Tests for equivalent or equal.
This is the same as the EORS
instruction, except that the result is discarded.
Only Z
bit will be changed based on the equivalency test. Other CCR flags will remain unchanged.
Set if equal
Clear if not equal
Example:
xxxxxxxxxx
21TEQ r1, r2 @ If [r1] - [r2] is zero, sets Z flag
2 @ If [r1] - [r2] is NOT zero, clears Z flag
TST
(Test Bits)
Performs a bitwise AND
on two values and sets ALL the CCR flags.
This is the same as the ANDS
instruction, except that the result is discarded.
This is useful to test an individual bit in a register.
Example:
xxxxxxxxxx
21TST r0, #2_00100000 @ Test if bit 5 of r0 is 1. (prefix '#_2' means 'binary')
2BEQ LowerCase @ If bit 5 is 1 it is a lowercase letter.
CMP
(Compare)
Compares two values by subtracting one from another and sets all of the CCR flags.
Example:
xxxxxxxxxx
31CMP r0, r1 @ Performs [r0] - [r1] and sets the CCR flags
2 @ accordingly.
3BEQ Equal @ If [r0] - [r1] = 0, branch to Equal
CMN
(Compare Negate)
Negates the second operator then perform the compare. Sets ALL the bits of the CCR.
This is the same as the ADDS
instruction, except that the result is discarded.
Example:
xxxxxxxxxx
21CMN r0, r1 @ RTL: [r0] - (-[r1])
2 @ Essentially, [r0] + [r1].
No more new instructions here. We will see how the previously introduced instructions are used to implement different types of loop constructs.
Checks at the end of the construct.
Be careful. Some languages will always execute the loop one time regardless of the value of the counter.
C Code
xxxxxxxxxx
41for (i = 10; i > 0; i--)
2{
3 /* code */
4}
Assembly Code
xxxxxxxxxx
71 MOV r0, #10 @ Set up the loop counter
2
3ForLoop:
4 /* code */ @ Body of the loop
5
6 SUBS r0, r0, #1 @ Update counter at the bottom of the loop
7 BNE ForLoop @ Continue until count zero
Checks values at the top of the loop. If the condition is not met, the loop will not be entered.
C Code
xxxxxxxxxx
51while (count > 0)
2{
3 /* code */
4 count--;
5}
Assembly Code
xxxxxxxxxx
81WhileLoop:
2 CMP r0, #10 @ Test at the start of the loop
3 BEQ ExitWhileLoop @ If [r0] = 10, break the loop
4 /* code */
5 SUB r0, r0, #1 @ Decrement the counter
6 B WhileLoop @ Continue until count zero
7
8ExitWhileLoop: @ Done with the while loop
Checks at the bottom of the loop. The loop will always execute at least one time.
C Code
xxxxxxxxxx
41do
2{
3 /* code */
4} while (expression)
Assembly Code
xxxxxxxxxx
41UntilLoop:
2 /* code */
3 CMP r0, #0 @ Test at the bottom of the loop
4 BNE UntilLoop
Sometimes the combination of the parts of all three loops produces effective code.
For loop limits the number of iteration.
While loop test keeps from entering the loop if not necessary.
Until loop allows for an exit condition.
Regardless of the program language, it is always a good idea to have some code in place to ensure that you exit every loop.
Example:
xxxxxxxxxx
141 MOV r0, #10
2
3Loop:
4 CMP r1, #10 @ Test at the start of the while loop
5 BEQ ComboExit @ Leave the loop
6
7 /* code */
8
9 CMP r2, #0 @ Until loop test
10 BEQ ComboExit @ Leave the loop
11 SUBS r0, r0, #1 @ Decrement the for loop counter
12 BNE LoopStart
13
14ComboExit: @ Exit while loop
ARM allows each instruction to be conditionally executed based on the condition code.
xxxxxxxxxx
31ADDEQ r1, r2, r3 @ RTL: If Z = 1, then [r1] ← [r2] + [r3]
2
3ADDCC r1, r2, r3, LSL r4 @ RTL: If C = 0, then [r1] ← [r2] + [r3] * 2^[r4]
Conditional execution keeps us from from doing all the pesky branching for only one or two instructions that needs to be executed depending on the codes.
With a pipeline system, branches slows the processor down because the pipe has to be flushed to keep unwanted instructions from being executed.
For any ARM instruction, we can add the two letter condition codes to the instruction and make that instruction to be a conditional execution.
Example:
xxxxxxxxxx
51/* if ((a == b) && (c == d)) e++; */
2
3CMP r0, r1 @ r0 is a and r1 is b
4CMPEQ r2, r3 @ r2 is c and r3 is d
5ADDEQ r4, r4, #1 @ r4 is e
This does short circuit. If the result of the first comparison is NOT EQUAL, then the second and third comparisons are bypassed (annulled or squashed).
Depending on the CPU, it may be faster to have several squashed instructions than to execute a branch statement.