公司动态

Linux x64调用约定

📅 2026/7/15 23:25:30
Linux x64调用约定
Linux x64调用约定64位Linux以及macOS、FreeBSD等类Unix系统遵循的调用约定正式名称为System V AMD64 ABI。这是x86-64架构下最主流的非Windows调用标准。1. 参数传递整数和指针参数按顺序优先使用寄存器只有超过6个时才使用栈参数顺序寄存器你代码中的体现第1个rdimain的argc被存在edirdi的低32位第2个rsimain的argv被存在rsi第3个rdx-第4个rcx-第5个r8-第6个r9-浮点数/向量参数如果参数是float或double则使用xmm0~xmm7寄存器与整数寄存器互不冲突。2. 返回值传递整数/指针放在rax中你的代码最后mov eax, 0x0就是将返回值0放入rax。128位大结构体使用rdx:rax组合返回。3. 栈对齐16字节规则System V ABI 强制要求在call指令执行之前栈指针%rsp必须是 16 的倍数即地址末位为 0。4. 红色区域Red Zone—— Linux 特有的优化%rsp指针下方即地址更低的区域有128 字节0x80是被保证不会被信号或中断异步破坏的。这意味着不调用其他函数的“叶函数”可以直接使用rsp-0x80以内的空间存放局部变量无需执行sub rsp来分配栈帧。你的main调用了puts属于非叶函数所以它不能用 Red Zone必须老老实实sub rsp分配空间。5. 寄存器保留规则谁负责保存为了防止函数调用时数据丢失寄存器被划分为两类类型寄存器列表规则调用者保存Caller-savedrax,rdi,rsi,rdx,rcx,r8,r9,r10,r11如果调用者觉得这些寄存器的值以后还有用必须在call之前自己压栈保存。被调用的函数可以随意修改它们。被调用者保存Callee-savedrbx,rbp,r12,r13,r14,r15被调用的函数必须在使用前将它们压栈并在返回前恢复原值。6. 第7个及之后的参数怎么传如果参数超过 6 个多余的参数从右向左压入栈中与Windows不同Windows是前4个用寄存器第5个开始压栈。而且这些栈上的参数归调用者负责清理无需ret N调用者直接调整rsp即可。