These are simplified examples I came up with to go along with William Woodruff's excellent blog post on x86-64 addressing modes.
All the examples are compiled with GCC -O3 or -Os, which is indicative of what the compiler thinks the best option is in practice.
Use case: Indexing into a byte array (whose address is not fixed)
char f(char buf[], int index)
{
return buf[index];
}
movsx rsi, esi
movzx eax, BYTE PTR [rdi+rsi]
ret
https://godbolt.org/z/sWezc66e4
Use case: fixed index into an array
int f(int a[])
{
return a[2];
}
mov eax, DWORD PTR [rdi+8]
ret
https://godbolt.org/z/PxGxfMrx3
Use case: get member of struct
struct S {
int a;
int b;
};
int f(struct S *s)
{
return s->b;
}
mov eax, DWORD PTR [rdi+4]
ret
https://godbolt.org/z/eTa1dvva9
Use case: indexing into a struct member array
struct string
{
int len;
char data[];
};
char f(struct string *s, int i)
{
return s->data[i];
}
movsx rsi, esi
movzx eax, BYTE PTR [rsi+4+rdi]
ret
https://godbolt.org/z/3Mzo4rdnd
Use case: indexing into a byte array by index + constant
char f(char s[], int i)
{
return s[i+1];
}
movsx rsi, esi
movzx eax, BYTE PTR [rsi+1+rdi]
ret
https://godbolt.org/z/aY35nbP1W
Use case: indexing into an int array
int f(int a[], int i)
{
return a[i];
}
movsx rsi, esi
mov eax, DWORD PTR [rdi+rsi*4]
ret
https://godbolt.org/z/G9na1xr7P
Use case: indexing into a static array
int tbl[10];
int foo(int i)
{
return tbl[i];
}
foo:
movsx rdi, edi
mov eax, DWORD PTR tbl[0+rdi*4]
ret
tbl:
.zero 40
https://godbolt.org/z/h3fG1qf5W
Use case: Aside from the 2D array access, this also models an array access like a[i+1]
.
int f(int a[], int i)
{
return a[i+1];
}
movsxd rax, esi
mov eax, dword ptr [rdi + 4*rax + 4]
ret