在汇编中,你如何处理C struct?

时间:2011-07-01 15:04:11

标签: assembly

例如,如何为此syscall sys_wait4准备参数:

 asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru)
1120 {

如何处理程序集中的struct rusage

在程序集中处理struct的hello world示例对我来说已经足够了:)

1 个答案:

答案 0 :(得分:12)

struct的成员按顺序排列在内存中,可能带有填充,结构的地址通常是其第一个成员的地址。

struct Bar {
    int x;
    int y;
};

struct Foo {
    struct Bar b;
    double d;
    int i;
};

struct Foo f;

我们假设&f0x10。然后,&f.b.xFoo的第一个成员的第一个成员)也是0x10&f.b.y0x14,因为f.b.x为四个字节(假设为32位计算机)。 &f.d0x18&f.i0x20f(换句话说,&f + 1)未占用的第一个地址是0x24

所以你需要在汇编中做的就是确保你有结构成员的空间(堆栈或堆),并用适当的数据填充空格,并将第一个成员的地址传递给函数

对于实际涉及汇编的示例,您可以通过编写一个小型测试程序并使用gcc -S -O0 -g编译它来轻松生成它,这将为您的C代码生成汇编代码。例如:

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;
}

在汇编输出中,除其他外,您将看到(注意:这是64位ASM):

movl    $42, -32(%rbp)
movl    $9, -28(%rbp)
movabsq $4614253070214989087, %rax
movq    %rax, -24(%rbp)
movl    $8, -16(%rbp)

如您所见,值42,9(位模式为3.14的整数)和8加载到地址-32,-28,-24和-16(相对于基指针) )。我只有一个方便的Solaris盒子,所以我不能使用asmlinkage(它指定函数参数必须在堆栈而不是寄存器中传递),所以在函数调用之前,我们看到有效正在加载到寄存器中的结构的地址:

leaq    -32(%rbp), %rax
movq    %rax, %rdi

使用asmlinkage,您会看到此有效地址被压入堆栈。

相关问题