Quiz Entry - updated: 2026.07.10
How does assembly access a structure member, and how are the offsets determined?
Via a fixed compile-time offset from the struct's base address — e.g. movl %edx, 12(%rax) writes the member at offset 12.
The compiler knows every member's offset at compile time (from the layout rules), so member access is just base + constant_offset — there's no runtime arithmetic to find a field.
struct rec { int a[3]; int i; struct rec *n; }; // i is at offset 12
void set_i(struct rec *r, int val) { r->i = val; }
Assembly:
# %rax = r (base pointer), %edx = val
movl %edx, 12(%rax) # Mem[r + 12] = val -> writes r->i
Key points:
rholds the address of the struct's first byte; members are reached by adding their constant offset.- Offsets are baked into the instruction as displacements —
12(%rax)literally encodes the number 12. No lookup, no calculation at runtime. - To get a pointer to a member (e.g.
&r->a[idx]), the compiler useslea:leaq (%rdi,%rsi,4), %raxcomputes the address ofr->a[idx]without dereferencing it.
Tip: When reverse-engineering, a cluster of accesses like 8(%rdi), 16(%rdi), 0(%rdi) off one base register is a strong fingerprint of struct field access — the constants are the field offsets.
Go deeper:
struct in C (Wikipedia) — the C struct and its members.
Data structure alignment (Wikipedia) — how alignment fixes each member's offset.