1.20. ARRAYS
MOVS R0, #0x1C
STR R0, [SP,#0x64+var_2C]
MOVS R0, #0x1E
STR R0, [SP,#0x64+var_28]
MOVS R0, #0x20
STR R0, [SP,#0x64+var_24]
MOVS R0, #0x22
STR R0, [SP,#0x64+var_20]
MOVS R0, #0x24
STR R0, [SP,#0x64+var_1C]
MOVS R0, #0x26
STR R0, [SP,#0x64+var_18]
MOV R4, 0xFDA ; "a[%d]=%d\n"
MOV R0, SP
ADDS R6, R0, #4
ADD R4, PC
B loc_2F1C
; second loop begin
loc_2F14
ADDS R0, R5, #1
LDR.W R2, [R6,R5,LSL#2]
MOV R5, R0
loc_2F1C
MOV R0, R4
MOV R1, R5
BLX _printf
CMP R5, #0x13
BNE loc_2F14
LDR.W R0, [R8]
LDR R1, [SP,#0x64+canary]
CMP R0, R1
ITTTT EQ ; is canary still correct?
MOVEQ R0, #0
ADDEQ SP, SP, #0x54
LDREQ.W R8, [SP+0x64+var_64],#4
POPEQ {R4-R7,PC}
BLX ___stack_chk_fail
First of all, as we see, LLVM “unrolled” the loop and all values were written into an array one-by-one, pre-
calculated, as LLVM concluded it can work faster. By the way, instructions in ARM mode may help to do
this even faster, and finding this could be your homework.
At the function end we see the comparison of the “canaries”—the one in the local stack and the correct
one, to whichR8points.
If they are equal to each other, a 4-instruction block is triggered byITTTT EQ, which contains writing 0 in
R0, the function epilogue and exit. If the “canaries” are not equal, the block being skipped,
and the jump to___stack_chk_failfunction will occur, which, perhaps will halt execution.
1.20.4 One more word about arrays
Now we understand why it is impossible to write something like this in C/C++ code:
void f(int size)
{
int a[size];
...
};
That’s just because the compiler must know the exact array size to allocate space for it in the local stack
layout on at the compiling stage.
If you need an array of arbitrary size, allocate it by usingmalloc(), then access the allocated memory
block as an array of variables of the type you need.