Reverse Engineering for Beginners

(avery) #1

CHAPTER 12. CONDITIONAL JUMPS CHAPTER 12. CONDITIONAL JUMPS


12.3.2 ARM.


Optimizing Keil for ARM mode also uses the conditional instructionsADRcc:


Listing 12.21: Optimizing Keil 6/2013 (ARM mode)

f PROC
; compare input value with 10
CMP r0,#0xa
; if comparison result is EQual, copy pointer to the "it is ten" string into R0
ADREQ r0,|L0.16| ; "it is ten"
; if comparison result is Not Equal, copy pointer to the "it is not ten" string into R0
ADRNE r0,|L0.28| ; "it is not ten"
BX lr
ENDP


|L0.16|
DCB "it is ten",0
|L0.28|
DCB "it is not ten",0


Without manual intervention, the two instructionsADREQandADRNEcannot be executed in the same run.


Optimizing Keil for Thumb mode needs to use conditional jump instructions, since there are no load instructions that support
conditional flags:


Listing 12.22: Optimizing Keil 6/2013 (Thumb mode)

f PROC
; compare input value with 10
CMP r0,#0xa
; jump to |L0.8| if EQual
BEQ |L0.8|
ADR r0,|L0.12| ; "it is not ten"
BX lr
|L0.8|
ADR r0,|L0.28| ; "it is ten"
BX lr
ENDP


|L0.12|
DCB "it is not ten",0
|L0.28|
DCB "it is ten",0


12.3.3 ARM64


Optimizing GCC (Linaro) 4.9 for ARM64 also uses conditional jumps:


Listing 12.23: Optimizing GCC (Linaro) 4.9

f:
cmp x0, 10
beq .L3 ; branch if equal
adrp x0, .LC1 ; "it is ten"
add x0, x0, :lo12:.LC1
ret
.L3:
adrp x0, .LC0 ; "it is not ten"
add x0, x0, :lo12:.LC0
ret
.LC0:
.string "it is ten"
.LC1:
.string "it is not ten"


That is because ARM64 does not have a simple load instruction with conditional flags, likeADRccin 32-bit ARM mode or
CMOVcc in x86 [ARM13a, p390, C5.5]. It has, however, “Conditional SELect” instruction (CSEL), but GCC 4.9 does not seem
to be smart enough to use it in such piece of code.

Free download pdf