Linux / x86-64系统调用中的结构体对于汇编程序员的布局?

许多linux / x86-64系统调用接受指向结构的指针作为参数。

例如stat(2)的第二个参数是struct stat*

  struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for file system I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ }; 

这意味着如果你想从纯集合中调用系统调用,那么你就不得不知道每个types有多大的规则以及成员之间是否存在用于alignment的填充等等。

C标准是否将这个开放性定义为(编译器)实现,还是可以从标准中确定(假设原始types的大小是已知的)?

如果保持开放状态,内核或x86-64体系结构是如何定义的? 还是只是编译内核碰巧编译的问题?

(这是给我的结构我需要计算该成员相对于结构的地址的起始偏移量的一些成员)

Solutions Collecting From Web of "Linux / x86-64系统调用中的结构体对于汇编程序员的布局?"

C标准中没有定义结构的布局,但在ABI定义中,在你的情况下是System V AMD64 ABI。 也就是说,总的来说,布局是依赖于操作系统的,所有针对该操作系统的编译器都必须符合ABI(尽管如果你知道自己在做什么,大多数编译器都可以选择生成不同的布局)。 ABI还定义了如何将参数传递给函数,如何返回值,必须跨越调用保留哪些寄存器,等等。

您需要的ABI定义应该在http://www.x86-64.org/上提供 (似乎是下来了)

在Linux / x86-64下:

一个字节是8位。 大小和内存地址以1个字节为单位。

原始类型

原始类型有一个等于它们大小的对齐方式:

原始类型的大小(和路线)是:

 bool 1 char 1 short 2 int 4 long 8 long long 8 __int128 16 void* 8 float 4 double 8 long double 16 __float128 16 __m64 8 __m128 16 

结构,工会和阵列

  • 结构(和联合)对齐是任何组件的最大对齐方式。

  • 每个结构成员都分配到具有适当对齐的最低可用偏移量。

  • 结构的大小被四舍五入到最接近的对齐倍数。

  • 结构和联合对象可能需要填充来满足大小和对齐约束。 任何填充的内容都是未定义的。

  • 少于16个字节的数组具有其元素类型的对齐。

  • 16字节或更长的数组具有(a)16中较高的对齐; 和(b)其元素类型的对齐。