Remember the discussion in Section 8.5 of how LDS and STS worked? Towards the end of that section, we saw how an array of integers can be added up using LDS. The following C program and the subsequent CSC-1 assembler program implement that program directly, using pointers rather than array indexes as in the last section.
main() { int array[5]; /* contains 8, 2, 1, 4, 6 */ int sum; int *pointr; int i; int max = 5; pointr = &array[0]; sum = 0; i = 0; while (i < max) { /* could have used a for loop here */ sum += *pointr; pointr++; i++; } }
Some concessions were made to clarity and to enable the C code to be more closely tied to the following CSC-1 assembler version. A while loop was used instead of a for-loop for this reason and some other contractions were omitted as well. For example, the while loop could have been squished down to:
while (i++ < max) sum += *pointer++;
Here is the CSC-1 assembler code for the C version above:
0: LDI 2500 ; Put the address of the array into pointer 1: STD POINTR 2: LDI 0 ; Put 0 into sum and i 3: STD SUM 4: STD I 5: LOOP: LOD MAX ; is i == max? 6: SUB I 7: JZ ENDLOOP; if so, then we are done 8: LOD POINTR ; Get pointer to current array element 9: A2S ; Save in S to be used in indirect load 10: LDS ; Actually fetch the value 11: ADD SUM ; Add current sum to this 12: STD SUM ; store back into sum 13: LOD POINTR ; Add 1 to the pointer 14: ADD ONE ; so that it points to the next element 15: STD POINTR ; for the next round of the loop 16: LOD I ; Add 1 to the counter 17: ADD ONE ; so we can know when we've looked at all 18: STD I ; the elements of the array 19: JMP LOOP ; Back to the top of the loop 20: ENDLOOP: HLT ; When done, halt the computer 21: MAX: NUM 5 ; maximum size of the array 22: I: NUM 0 ; loop counter 23: ONE: NUM 1 ; Constant 1 used to increment I =1000 1000: POINTR: NUM 0 ; a pointer to the current element of the array =1500 1500: SUM: NUM 0 ; will hold sum of all elements of array =2500 2500: ARRAY: NUM 8 ; The array of integer 2501: NUM 2 2502: NUM 1 2503: NUM 4 2504: NUM 6
Let's examine the heart of the while loop to see how indirect addressing is used.
POINTR is the pointer variable that is used to point at successive elements of the array. Though it would have been more natural to use something like array[i], the approach of using pointers is quite natural in C. POINTR is put at location 1000 in memory to tie it into the diagrams in Section 8.5. Likewise, the array occupies words 2500 through 2504 and the sum is in location 1500. The equals directive is an assembler command that tells the assembler to write the code so that these values are placed at the desired locations.
POINTR is set to point at the first word of the array by actually loading that address, 2500, and storing it into the pointer. C allows this to be done more easily without knowing exactly what the number is, by using the address-of operator, as in pointr = &array[0]; Recall that an array is addressed by its first element (or the first byte of the first element). There is really no other way to address a large chunk of memory in machine language.
The expression *pointr is what is called a dereferencing of a pointer. What this means is that the pointer is followed to the object that it points to and that object is fetched and used. This happens in instructions 8 through 10, leaving the value in A. Next we add SUM to that value and store it back into SUM. No elements of the array are changed in this program.
Then the pointer's value is increased by 1 so that it will point to the next element of the array. This takes 3 instructions, load, add and store, as does adding 1 to the loop counter.
The approach to arrays taken in this program differs from that in Section 9.6 where an explicit index variable is added to the base address. The base address of the array in the program above is 2500, but instead of adding 1 to it, we actually do pointer arithmetic on the pointer. When pointers are used for linked lists or graphs or other structures than arrays, they must be used as above; the array element notation is not available. But as we saw in Section 9.6, even array[i] gets turned into instructions that use LDS and STS.