Elements of a struct laid out sequentially in memory, possibly with the addition, and the address of the structure is usually the address of its first element.
struct Bar { int x; int y; }; struct Foo { struct Bar b; double d; int i; }; struct Foo f;
Say &f is 0x10 . Then &f.bx (the first member of the first member of Foo ) is also 0x10 . &f.by 0x14 , since fbx is four bytes (assuming a 32-bit machine). &f.d is 0x18 , and &f.i is 0x20 . The first address that is not occupied by f (in other words, &f + 1 ) is 0x24 .
So, all you need to do in the assembly is to make sure that you have (stack or heap) space for members of the structure and fill the gap with the appropriate data, and pass the address of the first element of the function.
As for the example, which is actually related to the assembly, you can easily create it yourself by writing a small test program and compile it with gcc -S -O0 -g , which will create the assembly code for your C code. For example:
int func(struct Foo * foo) { return foo->bx + foo->i; } int main() { struct Foo foo; foo.bx = 42; foo.by = 9; foo.d = 3.14; foo.i = 8; func(&foo); return 0; }
In the output of the assembly, you will see, among other things (note: this is a 64-bit ASM):
movl $42, -32(%rbp) movl $9, -28(%rbp) movabsq $4614253070214989087, %rax movq %rax, -24(%rbp) movl $8, -16(%rbp)
As you can see, the values ββ42, 9 (an integer whose bit-bit is 3.14) and 8 are loaded into the addresses -32, -28, -24 and -16 (relative to the base pointer). I have only the Solaris field, so I could not use asmlinkage (which indicates that the arguments to the function should be passed on the stack, not to the registers), so immediately before the function is called, we see the effective address of the structure loaded into the register:
leaq -32(%rbp), %rax movq %rax, %rdi
With asmlinkage instead you will see that this effective address is asmlinkage stack.