1.20. ARRAYS
ARM + Non-optimizing Xcode 4.6.3 (LLVM) (Thumb mode)
Listing 1.251: Non-optimizing Xcode 4.6.3 (LLVM) (Thumb mode)
_insert
value = -0x10
z = -0xC
y = -8
x = -4
; allocate place in local stack for 4 values of int type
SUB SP, SP, #0x10
MOV R9, 0xFC2 ; a
ADD R9, PC
LDR.W R9, [R9] ; get pointer to array
STR R0, [SP,#0x10+x]
STR R1, [SP,#0x10+y]
STR R2, [SP,#0x10+z]
STR R3, [SP,#0x10+value]
LDR R0, [SP,#0x10+value]
LDR R1, [SP,#0x10+z]
LDR R2, [SP,#0x10+y]
LDR R3, [SP,#0x10+x]
MOV R12, 2400
MUL.W R3, R3, R12
ADD R3, R9
MOV R9, 120
MUL.W R2, R2, R9
ADD R2, R3
LSLS R1, R1, #2 ; R1=R1<<2
ADD R1, R2
STR R0, [R1] ; R1 - address of array element
; deallocate chunk in local stack, allocated for 4 values of int type
ADD SP, SP, #0x10
BX LR
Non-optimizing LLVM saves all variables in local stack, which is redundant.
The address of the array element is calculated by the formula we already saw.
ARM + Optimizing Xcode 4.6.3 (LLVM) (Thumb mode)
Listing 1.252: Optimizing Xcode 4.6.3 (LLVM) (Thumb mode)
_insert
MOVW R9, #0x10FC
MOV.W R12, #2400
MOVT.W R9, #0
RSB.W R1, R1, R1,LSL#4 ; R1 - y. R1=y<<4 - y = y16 - y = y15
ADD R9, PC
LDR.W R9, [R9] ; R9 = pointer to a array
MLA.W R0, R0, R12, R9 ; R0 - x, R12 - 2400, R9 - pointer to a. R0=x2400 + ptr to a
ADD.W R0, R0, R1,LSL#3 ; R0 = R0+R1<<3 = R0+R18 = x2400 + ptr to a + y158 =
; ptr to a + y304 + x6004
STR.W R3, [R0,R2,LSL#2] ; R2 - z, R3 - value. address=R0+z4 =
; ptr to a + y304 + x6004 + z*4
BX LR
The tricks for replacing multiplication by shift, addition and subtraction which we already saw are also
present here.
Here we also see a new instruction for us:RSB(Reverse Subtract).
It works just asSUB, but it swaps its operands with each other before execution. Why?SUBandRSBare
instructions, to the second operand of which shift coefficient may be applied: (LSL#4).
But this coefficient can be applied only to second operand.