在汇编中,你如何处理C结构体?
比如这个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 示例对我来说就足够了:)
For example, how to prepare parameters for this syscall sys_wait4
:
asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru)
1120 {
How to deal with struct rusage
in assembly?
A hello world example to deal with struct
in assembly is enough for me:)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
结构体的成员在内存中按顺序排列,可能有填充,结构体的地址通常是其第一个成员的地址。
假设
&f
是0x10
。那么,&fbx
(Foo
的第一个成员的第一个成员)也是0x10
。&fby
是0x14
,因为fbx
是四个字节(假设是 32 位机器)。&fd
为0x18
,&fi
为0x20
。没有被f
占用的第一个地址(即&f + 1
)是0x24
。因此,在汇编中您需要做的就是确保有用于结构体成员的(堆栈或堆)空间,并用适当的数据填充该空间,并将第一个成员的地址传递给函数。
至于实际涉及汇编的示例,您可以通过编写一个小型测试程序并使用 gcc -S -O0 -g 编译它来轻松地自己生成它,这将为您的 C 代码生成汇编代码。例如:
在汇编输出中,您将看到(注意:这是 64 位 ASM):
如您所见,值 42、9(位模式为 3.14 的整数)和8 被加载到地址-32、-28、-24 和-16(相对于基指针)。我手头只有一个 Solaris 盒子,所以我无法使用
asmlinkage
(它指定函数参数必须在堆栈上传递,而不是在寄存器中传递),因此在函数调用之前,我们查看正在加载到寄存器中的结构的有效地址:使用
asmlinkage
,您会看到该有效地址被推入堆栈。The members of a
struct
are laid out sequentially in memory, possibly with padding, and the address of the struct is typically the address of its first member.Let's say that
&f
is0x10
. Then,&f.b.x
(the first member of the first member ofFoo
) is also0x10
.&f.b.y
is0x14
, sincef.b.x
is four bytes (assuming a 32-bit machine).&f.d
is0x18
, and&f.i
is0x20
. The first address that is not occupied byf
(in other words,&f + 1
) is0x24
.So all you need to do in assembly is to make sure that you have (stack or heap) space for the members of the struct, and fill the space with appropriate data, and pass the address of the first member to the function.
As for an example that actually involves assembly, you could easily produce that yourself by writing a small test program and compile it with
gcc -S -O0 -g
, which will produce assembly code for your C code. For example:In the assembly output, you will, among other things, see (note: this is 64-bit ASM):
As you can see, the values 42, 9, (integer whose bit pattern is that of 3.14), and 8 being loaded into the addresses -32, -28, -24, and -16 (relative to the base pointer). I only have a Solaris box handy, so I couldn't use
asmlinkage
(which specifies that the function arguments must be passed on the stack rather than in the registers), so immediately before the function call, we see the effective address of the struct being loaded into a register:With
asmlinkage
, you'd instead see this effective address being pushed onto the stack.