CHAPTER 12. CONDITIONAL JUMPS CHAPTER 12. CONDITIONAL JUMPS
.text:000000E0 70 80 BD A8 LDMGEFD SP!, {R4-R6,PC}
.text:000000E4 70 40 BD E8 LDMFD SP!, {R4-R6,LR}
.text:000000E8 19 0E 8F E2 ADR R0, aAB_1 ; "a<b\n"
.text:000000EC 99 18 00 EA B __2printf
.text:000000EC ; End of function f_signed
Many instructions in ARM mode could be executed only when specific flags are set. E.g. this is often used when comparing
numbers.
For instance, theADDinstruction is in fact namedADDALinternally, whereALstands forAlways, i.e., execute always. The
predicates are encoded in 4 high bits of the 32-bit ARM instructions (condition field). TheBinstruction for unconditional
jumping is in fact conditional and encoded just like any other conditional jump, but hasALin thecondition field, and it
impliesexecute ALways, ignoring flags.
TheADRGTinstruction works just likeADRbut executes only in case the previousCMPinstruction founds one of the numbers
greater than the another, while comparing the two (Greater Than).
The nextBLGTinstruction behaves exactly asBLand is triggered only if the result of the comparison was the same (Greater
Than).ADRGTwrites a pointer to the stringa>b\nintoR0andBLGTcallsprintf(). therefore, these instructions with
suffix-GTare to execute only in case the value inR0(which isa) is bigger than the value inR4(which isb).
Moving forward we see theADREQandBLEQinstructions. They behave just likeADRandBL, but are to be executed only if
operands were equal to each other during the last comparison. AnotherCMPis located before them (because theprintf()
execution may have tampered the flags).
Then we seeLDMGEFD, this instruction works just likeLDMFD^1 , but is triggered only when one of the values is greater or
equal than the other (Greater or Equal).
The LDMGEFD SP!, {R4-R6,PC} instruction acts like a function epilogue, but it will be triggered only ifa>=b, and
only then the function execution will finish.
But if that condition is not satisfied, i.e.,a<b, then the control flow will continue to the next“LDMFD SP!, {R4-R6,LR}”
instruction, which is one more function epilogue. This instruction restores not only theR4-R6registers state, but alsoLR
instead ofPC, thus, it does not returns from the function.
The last two instructions callprintf()with the string «a<b\n» as a sole argument. We already examined an unconditional
jump to theprintf()function instead of function return in «printf()with several arguments» section (6.2.1 on page 45).
f_unsignedis similar, only theADRHI,BLHI, andLDMCSFDinstructions are used there, these predicates (HI = Unsigned
higher, CS = Carry Set (greater than or equal)) are analogous to those examined before, but for unsigned values.
There is not much new in themain()function for us:
Listing 12.7:main()
.text:00000128 EXPORT main
.text:00000128 main
.text:00000128 10 40 2D E9 STMFD SP!, {R4,LR}
.text:0000012C 02 10 A0 E3 MOV R1, #2
.text:00000130 01 00 A0 E3 MOV R0, #1
.text:00000134 DF FF FF EB BL f_signed
.text:00000138 02 10 A0 E3 MOV R1, #2
.text:0000013C 01 00 A0 E3 MOV R0, #1
.text:00000140 EA FF FF EB BL f_unsigned
.text:00000144 00 00 A0 E3 MOV R0, #0
.text:00000148 10 80 BD E8 LDMFD SP!, {R4,PC}
.text:00000148 ; End of function main
That is how you can get rid of conditional jumps in ARM mode.
Why is this so good? Read here:33.1 on page 436.
There is no such feature in x86, except theCMOVccinstruction, it is the same asMOV, but triggered only when specific flags
are set, usually set byCMP.
Optimizing Keil 6/2013 (Thumb mode)
Listing 12.8: Optimizing Keil 6/2013 (Thumb mode)
.text:00000072 f_signed ; CODE XREF: main+6
.text:00000072 70 B5 PUSH {R4-R6,LR}
(^1) LDMFD