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 示例对我来说就足够了:)
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
,您会看到这个有效地址被推入堆栈。
我见过有些人使用“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