例如,如何为此准备参数syscall sys_wait4
:
asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru)
1120 {
struct rusage
装配时如何处理?
在汇编中处理一个 hello world 示例struct
对我来说就足够了:)
例如,如何为此准备参数syscall sys_wait4
:
asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru)
1120 {
struct rusage
装配时如何处理?
在汇编中处理一个 hello world 示例struct
对我来说就足够了:)
a 的成员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
,您会看到这个有效地址被压入堆栈。