CS 202 - Notes 2018-11-05

Array access examples

Declaration Element size (in bytes) Total size (in bytes) Start address Access element i
char A[8] 1 8 xa xa + i
int B[12] 4 48 xb xb + 4i
char * C[10] 8 80 xc xc + 8i
long D[5] 8 40 xd xd + 8i
short E[6] 2 12 xe xe + 2i

Now, if we say that the array is stored in %rax, i is stored in %rcx, and our destination is %rdx (or %edx or %dl as appropriate)

Expression Type Value Assembly
A[i] char M[x<sub>a</sub> + i] movb (%rax, %rcx), %dl
A[4] char M[x<sub>a</sub> + 4] movb 4(%rax), %dl
B[i] int M[x<sub>b</sub> + i*4] movl (%rax, %rcx,4), %edx
B[5] int M[x<sub>b</sub> + 20] movl 20(%rax), %edx
C[i] char * M[x<sub>c</sub> + i*8] movq (%rax, %rcx,8), %rdx
D[i] long M[x<sub>d</sub> + i*8] movq (%rax, %rcx,8), %rdx
E + 4 short * x<sub>e</sub> + 8 leaq 8(%rax), %rdx
E + i - 3 short * x<sub>e</sub> + i*2 - 6 leaq -6(%rax, %rcx, 2), %rdx
&B[i] int * x<sub>eb</sub> + i*4 leaq (%rax, %rcx, 4), %rdx

Things to note here:

  • C[i] and D[i] are the same under the hood
  • In assembly, we had to multiply in the data sizes ourselves

The larger point here is that assembly has no sense of "type". The types that we are used to in C (and other languages) are a convenient abstraction provided for us by the compiler. It is the compiler that translates these into the appropriate memory accesses. It is also the compiler that makes pointer arithmetic work the way that we are accustomed to, multiplying whatever we are adding to the pointer to the size of the data type pointed to by the pointer (e.g., E+4 above).

Last Updated: 11/5/2018, 5:15:30 PM