Indirect addressing, including memory indirect addressing, which takes a base address (register), an index (register), a size (immediate), two offsets (immediate), and an address stored in memory somewhere.
You could, in one single instruction,
struct B {
int x, y, z;
};
struct A {
int a, b, c;
struct B *ptr;
};
void func(struct A *array, int i) {
array[i].ptr->z = 3;
}
Unless I am remembering how it works incorrectly.