1.20. ARRAYS
loc_4A0
CMP R4, #20 ; i<20?
BLT loc_494 ; yes, run loop body again
; second loop
MOV R4, #0 ; i
B loc_4C4
loc_4B0
LDR R2, [SP,R4,LSL#2] ; (second printf argument) R2=(SP+R4<<4) (same as (SP+⤦
ÇR4*4))
MOV R1, R4 ; (first printf argument) R1=i
ADR R0, aADD ; "a[%d]=%d\n"
BL __2printf
ADD R4, R4, #1 ; i=i+1
loc_4C4
CMP R4, #20 ; i<20?
BLT loc_4B0 ; yes, run loop body again
MOV R0, #0 ; value to return
ADD SP, SP, #0x50 ; deallocate chunk, allocated for 20 int variables
LDMFD SP!, {R4,PC}
inttype requires 32 bits for storage (or 4 bytes),
so to store 20intvariables 80 (0x50) bytes are needed. So that is why theSUB SP, SP, #0x50
instruction in the function’s prologue allocates exactly this amount of space in the stack.
In both the first and second loops, the loop iteratoriis placed in theR4register.
The number that is to be written into the array is calculated asi∗ 2 , which is effectively equivalent to
shifting it left by one bit,
soMOV R0, R4,LSL#1instruction does this.
STR R0, [SP,R4,LSL#2]writes the contents ofR0into the array.
Here is how a pointer to array element is calculated:SPpoints to the start of the array,R4isi.
So shiftingileft by 2 bits is effectively equivalent to multiplication by 4 (since each array element has a
size of 4 bytes) and then it’s added to the address of the start of the array.
The second loop has an inverseLDR R2, [SP,R4,LSL#2]instruction. It loads the value we need from the
array, and the pointer to it is calculated likewise.
Optimizing Keil 6/2013 (Thumb mode)
_main
PUSH {R4,R5,LR}
; allocate place for 20 int variables + one more variable
SUB SP, SP, #0x54
; first loop
MOVS R0, #0 ; i
MOV R5, SP ; pointer to first array element
loc_1CE
LSLS R1, R0, #1 ; R1=i<<1 (same as i2)
LSLS R2, R0, #2 ; R2=i<<2 (same as i4)
ADDS R0, R0, #1 ; i=i+1
CMP R0, #20 ; i<20?
STR R1, [R5,R2] ; store R1 to (R5+R2) (same R5+i4)
BLT loc_1CE ; yes, i<20, run loop body again
; second loop
MOVS R4, #0 ; i=0
loc_1DC