开发者

In assembly, how do you deal with C struct?

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 assemb开发者_StackOverflowly?

A hello world example to deal with struct in assembly is enough for me:)


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜