5.3. Looping Through Arrays

To loop through an array, we need to access successive memory addresses: something like x, x + 4, x + 8, … To use the LDR rd, [rn, #] syntax, we would have to list each memory address by hand. Alternatively, we could load x’s address into a register, and then modify that address each time we were ready to access the next item. But it is often useful to retain the base address of the array, so overwriting our copy of its address may not make sense.

To provide a flexible way to access parts of an array, another form of indicating an address for load and store instructions is provided for in ARM:

LDRrd, [rn, rm]

Access the memory at the byte address rn + rm, and store its value into rd. Similar [rn, rm] syntax is available for STR, LDRB, LDRSB, and STRB

If rn holds our base address, then rm can hold our offset - any time we access memory, those values will be added together.

This code sample demonstrates looping through an array using this technique. Note that we calculate the address of items in the array on line 24 by adding the base address stored in r2 with the offset stored in r5 and every time through the loop we add 4 to the offset (on line 29).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.data
@an array of 5 ints
myArray:     .word   10, 20, 30, 40, 50

arraySize:   .word   5     @size of myArray


.text
_start:
LDR   r1, =arraySize    @ r1 = &arraySize
LDR   r1, [r1]          @ r1 = arraySize

LDR   r2, =myArray      @ load myArray start address
                        @ r2 will always point at array start

MOV   r3, #0            @ r3 = loop counter
MOV   r5, #0            @ r5 = bytes into array to current element
MOV   r4, #0            @ r4 = total

B     looptest          @ jump ahead to loop test

loopstart:
@Calculate address of current element by adding offset r5 to base address
LDR   r6, [r2, r5]      @ r6 = element at address r2 + r5
ADD   r4, r4, r6        @ total += current value

@go to next step
ADD   r3, r3, #1        @ add one to counter
ADD   r5, r5, #4        @ add 4 to offset value for "current element"

looptest:
CMP   r3, r1            @ Compare counter r3 to size of array in r1
BLT   loopstart         @ If counter Less Than size, go back to start

end:
B     end               @stop here
Try sample

5.3.1. Looping over byte arrays

If we are working with bytes of memory, the index (loop counter) and offet will always be the same, so we can use one register to represent both. Index 2 will be 2 bytes in, index 5, will be 5 bytes in, etc…

The code sample below totals the values in myArray using a loop. It is just like the sample above except that r3 serves as both the array counter (index) and the memory offset for each element. And as we load elements of the array we have to use LDRSB to load them as bytes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
.data
@an array of 4 SIGNED bytes
myArray:       .byte   4, 2, -1, 10
.align   @make sure we are padded to a full word
myArraySize:   .word   4

.text
_start:
LDR   r1, =myArraySize     @ r1 = &myArraySize
LDR   r1, [r1]             @ r1 = myArraySize - it is a word, use LRB

LDR   r2, =myArray         @ load myArray start address
                           @ r2 will always point at array start

MOV   r3, #0               @ r3 = loop counter
MOV   r4, #0               @ r4 = total

B     looptest             @ jump ahead to loop test

loopstart:
@Load array item - it is a byte so use LDRSB
LDRSB r6, [r2, r3]         @ r6 = element at address r2 + r3
ADD   r4, r4, r6           @ total += current value

@go to next step
ADD   r3, r3, #1           @ add one to index

looptest:
CMP   r3, r1               @ Compare counter r3 to size of array in r1
BLT   loopstart            @ If counter Less Than size, go back to start

end:
B     end                  @stop here
Try sample
You have attempted of activities on this page
Next Section - 5.4. Array Loop Shifted Index