如何确定从程序集调用的 stat 结构中的字段偏移量?
how to determine field offset in stat struct calling from assembly?
为了获得 struct stat
描述文件,可以调用 *stat 系列函数,这些函数将用结构值填充传递的指针所指向的内存。
在C中我们可以调用POSIX.1-2008offsetof宏,但是是宏,不可用在组装中。
如何从程序集中确定结构的大小以及如何确定字段的偏移量,以便提取必要的字段,如 st_size
、st_mode
等?
平台的 ABI 决定了 C 结构填充的规则。例如,x86-64 Linux 使用 the x86-64 System V ABI.
困难的方法:阅读 ABI 并自己解决。 x86 标签 wiki 中的链接。 (实际上并没有那么难,结构中对齐/填充的规则非常简单:每个成员都按照声明的顺序排列,并且自然对齐。这可能需要填充)。
简单的方法:让编译器为您计算偏移量,方法是编写一个存储到结构中的函数,然后查看 asm。
例如
#include <sys/stat.h>
void foo(struct stat *st) {
st->st_size = 1;
st->st_mode = 2; // different numbers so you know which field is which in the output
}
mov QWORD PTR [rdi+48], 1
mov DWORD PTR [rdi+24], 2
ret
为了获得 struct stat
描述文件,可以调用 *stat 系列函数,这些函数将用结构值填充传递的指针所指向的内存。
在C中我们可以调用POSIX.1-2008offsetof宏,但是是宏,不可用在组装中。
如何从程序集中确定结构的大小以及如何确定字段的偏移量,以便提取必要的字段,如 st_size
、st_mode
等?
平台的 ABI 决定了 C 结构填充的规则。例如,x86-64 Linux 使用 the x86-64 System V ABI.
困难的方法:阅读 ABI 并自己解决。 x86 标签 wiki 中的链接。 (实际上并没有那么难,结构中对齐/填充的规则非常简单:每个成员都按照声明的顺序排列,并且自然对齐。这可能需要填充)。
简单的方法:让编译器为您计算偏移量,方法是编写一个存储到结构中的函数,然后查看 asm。
例如
#include <sys/stat.h>
void foo(struct stat *st) {
st->st_size = 1;
st->st_mode = 2; // different numbers so you know which field is which in the output
}
mov QWORD PTR [rdi+48], 1
mov DWORD PTR [rdi+24], 2
ret