例如,如何为此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示例对我来说已经足够了:)
答案 0 :(得分:12)
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
,您会看到此有效地址被压入堆栈。