在汇编中,你如何处理C结构体?

问题描述 投票:0回答:2

比如这个如何准备参数

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 示例对我来说就足够了:)

assembly struct x86-64 gnu-assembler
2个回答
18
投票

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

struct Bar {
    int x;
    int y;
};

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

struct Foo f;

假设

&f
0x10
。那么,
&f.b.x
Foo
的第一个成员的第一个成员)也是
0x10
&f.b.y
0x14
,因为
f.b.x
是四个字节(假设是 32 位机器)。
&f.d
0x18
&f.i
0x20
。第一个未被
f
(即
&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
,您会看到这个有效地址被推入堆栈。


0
投票

我见过有些人使用“istruc”或其他东西,虽然我不知道“i”到底是什么意思,但我认为你可以使用这个。否则就这样称呼:

struct Human{
    int age;
    char[100] name;
}

Human human;
human.age = 20;
human.name = "Alexander";

那个:

_Human:
    ; note this will not affect anything,
    ; but is only for knowing what is going on
    _Human_name: db 0
    _Human_age:  db 0


name: db "Alexander", 0
lea esi, name

mov [_Human_age], 20
mov [_Human_name], esi
© www.soinside.com 2019 - 2024. All rights reserved.