4.7. ARM Trick - Conditional Execution

In ARM machine code, the first four bits of most instructions are reserved for a condition code:

313029282726252423222120191817161514131211109876543210
condition opcode and other information

In this assembled example code, there are a series of branches with different conditions. Notice that the first hex digit of the instruction is different for each one. The second hex digit is always ‘a’, which corresponds to ‘branch’. (The last 24 bits, the addresses, are different as well, as each instruction is one instruction closer to the branch target test.)

../_images/condition_code_samples.png

These same four conditional bits also exist in most basic (movement, bitwise, arithmetic) instructions. Which means that instead of using a compare and branch to skip instructions, we can do a comparison and use the result of it to specify whether or not to actually do the work in following instructions.

In the sample below, lines 13 and 14 are both always executed. But, if the condition code is

Line 13 only executes if the comparison on line 11 indicated equality. Line 14 only executes if it did not.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
   .data
   x:      .word   2
   y:      .word   0


   .text
   _start:
   LDR     r1, =x      @load x's address
   LDR     r1, [r1]    @r1 = x

   CMP     r1, #2      @test r1 vs 2 (calculate r1 - 2)

   MOVEQ   r2, #5      @only executed if CMP set status indicating values EQual
   MOVNE   r2, #3      @only executed if CMP set status indicating values Not Equal

   LDR     r3, =y      @load y's address
   STR     r2, [r3]    @store result back to y
Try sample

Why does this trick exist? Those 4 bits are valuable real estate in the machine instruction format. The answer is efficiency.

Using conditional execution in the sample above resulted in 3 lines of code to implement the if/else. An implementation using branches would result in 5 lines. Furthermore, executing branches can be a major source of slow downs in modern pipelined processors. So even in a larger if/else structure - one where the if and else each contained 5 instructions - we might very well be better off always executing all 10 instructions and just ignoring 5 of them than using branches to only execute the correct five instructions.

Note

Fun fact: the condition code for “always” is 1110 or hex E. That is why most normal instructions in ARM assembly start with E.

You have attempted of activities on this page