For example, how to prepare parameters for this syscall sys_wait4
:
asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru)
1120 {
How to deal with struct rusage
in assembly?
A hello world example to deal with struct
in assembly is enough for me:)
Structures, like arrays, are passed by reference, so as a parameter: they are just a 32-bit parameter (the pointer to the first structure member), and that pointer is pushed on the stack in the cases of cdecl and stdcall .
Data structures in assembly language, as in high-level languages, are nested structures composed of references, structs, and arrays. These structures are often dynamically allocated, which gives programs the capability of adjusting their memory usage to the immediate needs.
The members of a struct
are laid out sequentially in memory, possibly with padding, and the address of the struct is typically the address of its first member.
struct Bar {
int x;
int y;
};
struct Foo {
struct Bar b;
double d;
int i;
};
struct Foo f;
Let's say that &f
is 0x10
. Then, &f.b.x
(the first member of the first member of Foo
) is also 0x10
. &f.b.y
is 0x14
, since f.b.x
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 assembly is to make sure that you have (stack or heap) space for the members of the struct, and fill the space with appropriate data, and pass the address of the first member to the function.
As for an example that actually involves assembly, you could easily produce that yourself by writing a small test program and compile it with gcc -S -O0 -g
, which will produce assembly code for your C code. For example:
int func(struct Foo * foo) {
return foo->b.x + foo->i;
}
int main() {
struct Foo foo;
foo.b.x = 42;
foo.b.y = 9;
foo.d = 3.14;
foo.i = 8;
func(&foo);
return 0;
}
In the assembly output, you will, among other things, see (note: this is 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, (integer whose bit pattern is that of 3.14), and 8 being loaded into the addresses -32, -28, -24, and -16 (relative to the base pointer). I only have a Solaris box handy, so I couldn't use asmlinkage
(which specifies that the function arguments must be passed on the stack rather than in the registers), so immediately before the function call, we see the effective address of the struct being loaded into a register:
leaq -32(%rbp), %rax
movq %rax, %rdi
With asmlinkage
, you'd instead see this effective address being pushed onto the stack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With