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

时间:2013-01-16 09:50:23

标签: c linux linux-kernel x86 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 */
   };

这意味着如果你想从纯汇编中调用系统调用,你必须知道每个类型有多大的规则,以及成员之间是否有任何填充用于对齐目的,等等。

C标准是否将此开放定义为(编译器)实现定义,还是可以从标准确定(假设原始类型大小已知)?

如果它保持打开状态,内核或x86-64架构是否仍然定义它?或者仅仅是编译内核的编译器的问题?

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

2 个答案:

答案 0 :(得分:14)

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

您需要的ABI定义应该在http://www.x86-64.org/上提供(似乎已关闭)

答案 1 :(得分:0)

在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)元素类型的对齐。