CHAPTER 18. ARRAYS CHAPTER 18. ARRAYS
; 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 ; 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 whichR8
points. If they are equal to each other, a 4-instruction block is triggered byITTTT EQ, which contains writing 0 inR0, the
function epilogue and exit. If the “canaries” are not equal, the block being skipped, and the jump to___stack_chk_fail
function will occur, which, perhaps, will halt execution.
18.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.
Or use the C99 standard feature[ISO07, pp. 6.7.5/2], and it works like alloca() (5.2.4 on page 26) internally.
It’s also possible to use garbage collecting libraries for C. And there are also libraries supporting smart pointers for C++.
18.5 Array of pointers to strings
Here is an example for an array of pointers.
Listing 18.8: Get month name
#include <stdio.h>
const char* month1[]=
{
"January",
"February",
"March",
"April",
"May",