An array in C/C++ consists of one or more elements, all of the same data type, arranged contiguously in memory. An example is the C-style text strings we have been using in the past few chapters. So far, we have been accessing the elements sequentially, one immediately after the other. This array processing only requires the address of the beginning of the array.
To access a single element in an array we need to specify two address-related items:
The beginning of the array.
The number of the element to access.
For example, given the declaration in C:
int array[50];
you can store an integer, say \(123\text{,}\) in the \(i-th\) element with the statement
array[i] = 123;
In this example the beginning of the array is specified by using the name, and the number of the element is specified by the [...] syntax. The program in Listing 15.1.1 shows how to access each element in an array directly, both storing a value and reading it.
Listing 15.1.2 shows a way to access array elements in assembly language.
In the code sequence:
mov r3, r4, asl #2 @@ 4 * index
sub r2, fp, #12 @@ address of end of array
add r3, r2, r3 @@ index-th element beyond end
str r4, [r3, #-40] @@ minus length of array
the number of bytes from the beginning of the array to specified element is computed by multiplying the index number by four. Next, the address of the end of the array is computed. The byte offset of the specified element is added to the address of the end of the array, which leaves r3 pointing to an address beyond the end of the array. Storing the value (index number in this program) uses a negative offset equal to the total length (in bytes) of the array. So the net result is that the value is stored in the proper location in the array.
I do not know why the compiler writer decided to use this algorithm to access an array. I have used a more direct approach in Listing 15.1.3
In my algorithm I use r4 as the base register to hold the address of the beginning of the array and r5 to maintain the array element number (index):
add r4, fp, intArray @ address of array beginning
mov r5, 0 @ index = 0;
It is then a simple matter to access any element of the array by computing the byte offset from the beginning of the array, storing this value in a register, and using the register addressing mode (Section 11.1):
lsl r0, r5, 2 @ no, offset is 4 * index
str r5, [r4, r0] @ at index-th element