C Linux/x86-64系统调用中面向汇编程序员的结构布局?
许多linux/x86-64系统调用接受指向结构的指针作为参数 例如,C Linux/x86-64系统调用中面向汇编程序员的结构布局?,c,linux,linux-kernel,x86,x86-64,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_
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 */
};
这意味着,如果要从纯程序集调用syscall,则必须知道关于每个类型的大小的规则,以及成员之间是否有用于对齐的填充,等等
C标准是否将此打开状态留待(编译器)实现定义,还是可以从标准中确定(假设原语类型大小已知)
如果它保持打开状态,内核或x86-64体系结构是否定义了它?或者这只是内核编译时使用的编译器的问题
(即给定结构的某个成员,我需要计算该成员相对于结构地址的起始偏移量)结构的布局未在C标准中定义,而是在ABI定义中定义,在您的示例中是System V AMD64 ABI。也就是说,一般来说,布局依赖于操作系统,所有针对该操作系统的编译器都必须符合ABI(尽管如果您知道自己在做什么,大多数编译器都有生成不同布局的选项)。ABI还定义了如何将参数传递给函数、如何返回值、在调用过程中必须保留哪些寄存器等 您需要的ABI定义应该在Linux/x86-64下的(似乎已关闭)上可用: 一个字节是8位。大小和内存地址以1字节为单位 基本类型 基元类型的对齐方式与其大小相等: 基本体类型大小(和路线)为: 结构、联合和数组
- 结构(和联合)对齐是其任何组件的最大对齐
- 每个结构成员都被分配到具有适当偏移量的最低可用偏移量 对齐
- 结构的大小向上舍入为其对齐的最近倍数
- 结构和联合对象可能需要填充以满足大小和对齐要求 限制。任何填充物的内容均未定义
- 小于16字节的数组具有其元素类型的对齐方式
- 16字节或更长的数组具有(a)16中较高者的对齐方式;和(b)其元素类型的对齐
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