【问题标题】:Layout of structs in Linux/x86-64 syscalls for assembly programmers?面向汇编程序员的 Linux/x86-64 系统调用中的结构布局?
【发布时间】:2012-12-30 14:21:24
【问题描述】:

许多 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 架构是否以任何方式定义它?还是只是内核碰巧用哪个编译器编译的问题?

(给定结构的某个成员,我需要计算该成员相对于结构地址的起始偏移量)

【问题讨论】:

  • 我真的很想知道你为什么要从程序集中调用系统调用。我看不出这样做比在 C 中做有任何优势。
  • @JanHudec:“优势”是您了解 C 编译器的工作原理。

标签: c linux linux-kernel x86 x86-64


【解决方案1】:

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

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

【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-16
    • 2018-10-01
    • 1970-01-01
    • 2020-08-17
    • 2012-12-30
    • 2021-05-11
    • 1970-01-01
    • 2015-02-20
    相关资源
    最近更新 更多