函数调用寄存器规则

函数调用寄存器规则 所有 CPU 通用函数调用寄存器规则不管是 Intel、AMD、ARM全部遵守这 4 条规则参数规则前 N 个参数用约定寄存器传递超出部分用栈。返回值规则函数返回值必须放在固定的约定寄存器中。易失寄存器规则调用者保存函数可以随便修改调用者如果要保留值必须自己提前保存非易失寄存器规则被调用者保存函数不能破坏原有值如果使用必须先保存、后恢复调用者可以放心使用不用担心被改x86 (32 位IA-32)32 位 x86几乎不用寄存器传参全部用栈传参。核心规则传参全部通过 ** 栈stack** 传递返回值EAX存返回值64 位返回值用EDX:EAX调用者保存寄存器被调用函数可以随便改调用前需自己保存EAX, ECX, EDX被调用者保存寄存器被调用函数必须原样返回EBX, ESI, EDI, EBP栈帧EBP用作栈基址ESP是栈顶指针x86_64 (amd6464 位 x86)优先用寄存器传参速度远快于栈是现代 Linux/macOS/Windows 主流。整数 / 指针寄存器规范标准标注寄存器标准名称官方用途定义保存方说明%raxReturn Value函数返回值临时寄存器Caller Saved调用者保存函数返回值存在这里函数可随意修改%rbxBase Pointer被调用者保存寄存器Callee Saved被调用者保存函数必须保护返回前恢复原值%rcx4th Argument第 4 个函数参数临时寄存器Caller Saved函数可随意修改%rdx3rd Argument第 3 个函数参数临时寄存器Caller Saved函数可随意修改%rsi2nd Argument第 2 个函数参数临时寄存器Caller Saved函数可随意修改%rdi1st Argument第 1 个函数参数临时寄存器Caller Saved函数可随意修改%rbpFrame Pointer栈帧基址被调用者保存寄存器Callee Saved函数必须保护%rspStack Pointer栈顶指针-硬件维护不可随意修改%r85th Argument第 5 个函数参数临时寄存器Caller Saved函数可随意修改%r96th Argument第 6 个函数参数临时寄存器Caller Saved函数可随意修改%r10Temporary临时寄存器Caller Saved函数可随意修改%r11Temporary临时寄存器Caller Saved函数可随意修改%r12Callee Saved被调用者保存寄存器Callee Saved函数必须保护%r13Callee Saved被调用者保存寄存器Callee Saved函数必须保护%r14Callee Saved被调用者保存寄存器Callee Saved函数必须保护%r15Callee Saved被调用者保存寄存器Callee Saved函数必须保护标准调用规则官方定义参数传递前6 个整数 / 指针参数RDI → RSI → RDX → RCX → R8 → R9第 7 个及以上参数栈传递返回值整数 / 指针RAX128 位返回值RDX:RAX保存规则Caller Saved调用者保存RAX, RCX, RDX, RSI, RDI, R8-R11函数可直接修改调用者需自行备份Callee Saved被调用者保存RBX, RBP, R12-R15函数使用前必须入栈保存返回前出栈恢复ARM64 (AArch64) AAPCS64 官方标准文档ARM Architecture Reference Manual AAPCS64ARM 官方过程调用标准适用iOS/Android 手机、Mac M 系列、ARM 服务器通用寄存器X0~X31标准标注寄存器标准别名官方用途定义保存方约束X0Argument/Result第 1 个参数函数返回值Caller SavedVolatile函数可修改X1Argument第 2 个参数Caller Saved函数可修改X2Argument第 3 个参数Caller Saved函数可修改X3Argument第 4 个参数Caller Saved函数可修改X4Argument第 5 个参数Caller Saved函数可修改X5Argument第 6 个参数Caller Saved函数可修改X6Argument第 7 个参数Caller Saved函数可修改X7Argument第 8 个参数Caller Saved函数可修改X8Indirect Result间接返回地址寄存器Caller Saved函数可修改X9-X15Temporary临时寄存器Caller Saved函数可修改X16IP0内部过程调用寄存器Caller Saved函数可修改X17IP1内部过程调用寄存器Caller Saved函数可修改X18Platform Register平台保留寄存器-不可随意使用X19-X28Callee Saved被调用者保存寄存器Callee SavedNon-volatile函数必须保护原值X29FP (Frame Pointer)栈帧基址寄存器Callee Saved函数必须保护X30LR (Link Register)函数返回地址寄存器Callee Saved存储返回地址必须保护X31SP / Zero Register栈指针 / 零寄存器-硬件维护标准调用规则官方定义参数传递前8 个整数 / 指针参数X0 ~ X7第 9 个及以上参数栈传递返回值整数 / 指针X0128 位返回值X0 X1保存规则VolatileCaller SavedX0-X15, X16-X17函数可直接修改调用者自行备份Non-volatileCallee SavedX19-X29, LR(X30)函数必须入栈保存返回前恢复特殊寄存器LR (X30)存储函数返回地址无需像 x86 一样压栈SP (X31)栈指针硬件自动维护权威标准总结x86_64参数RDI, RSI, RDX, RCX, R8, R9前 6 个返回RAX易失RAX, RCX, RDX, RSI, RDI, R8-R11非易失RBX, RBP, R12-R15ARM64参数X0~X7前 8 个返回X0易失X0~X15非易失X19~X29, LR(X30)LoongArch64龙芯 64 位1. 参数传递前8 个整数 / 指针参数用寄存器R4 → R5 → R6 → R7 → R8 → R9 → R10 → R11第 9 个及以后 →栈2. 返回值普通返回值R0128 位返回值R0 R13. 临时寄存器调用者保存 / 易失函数可直接修改调用前需自己保存R0 ~ R11R23 ~ R314. 被调用者保存寄存器非易失函数使用必须保存并恢复R12 ~ R225. 特殊寄存器R1 (RA)返回地址寄存器存函数返回地址R2 (SP)栈指针R3 (FP)栈帧基址指针完整标准表寄存器用途定义保存方R0返回值 / 临时调用者R1 (RA)返回地址被调用者R2 (SP)栈指针硬件R3 (FP)帧指针被调用者R4-R11函数参数 1~8调用者R12-R22被调用者保存寄存器被调用者R23-R31临时寄存器调用者申威 64 位SW641. 参数传递前6 个整数 / 指针参数用寄存器R3 → R4 → R5 → R6 → R7 → R8第 7 个及以后 →栈2. 返回值普通 64 位返回值R0128 位返回值R0 R13. 临时寄存器调用者保存 / 易失函数可直接修改调用前需自己保存R0 ~ R9, R15, R26 ~ R314. 被调用者保存寄存器非易失函数使用必须入栈保存、返回恢复R10 ~ R23, R25 (FP)5. 特殊寄存器R26 (RA)返回地址寄存器存函数返回地址R24 (SP)栈指针R25 (FP)栈帧基址指针寄存器别名用途定义保存方R0RV函数返回值调用者R1-R2TMP临时寄存器调用者R3-R8ARG第 1~6 个函数参数调用者R9TMP临时寄存器调用者R10-R23SAV被调用者保存寄存器被调用者R24SP栈指针硬件R25FP栈帧指针被调用者R26RA返回地址调用者R27-R31TMP临时寄存器调用者应用场景场景自己写汇编函数、写系统调用、写启动代码必须严格遵守 ABI 规则否则调用会崩溃。具体用法调用函数前把参数放到约定寄存器函数返回后从约定寄存器拿返回值保存 / 恢复非易失寄存器避免破坏调用者数据例子写 Linux 系统调用必须用rax放系统调用号rdi、rsi、rdx、r10、r8、r9放参数场景写编译器、动态翻译、虚拟机编译器生成函数调用代码必须严格遵守寄存器规则。具体用法函数传参用哪些寄存器哪些寄存器可以当临时变量哪些寄存器必须保存恢复所有编译器GCC、Clang、MSVC都按这套规则生成代码。场景优化高频调用函数寄存器比内存快 100 倍以上优化核心就是尽量用寄存器。具体用法尽量让函数参数 ≤6 个x86_64或 ≤8 个arm64减少栈使用提升速度内联函数减少调用开销场景C 调用汇编、Python 调用 C、Java JNI、Go 调用 C跨语言调用100% 依赖寄存器调用规则。具体用法参数按规则放入寄存器调用后从约定寄存器取返回值JNI、FFI、ctypes 底层全是这套规则。场景栈溢出、ROP、劫持控制流必须精准控制寄存器才能完成利用。具体用法控制RDI/X0传参控制RAX/X0返回值构造调用栈与寄存器布局PWN 入门第一课背寄存器调用规则。场景函数挂钩、监控、日志、篡改参数Hook 必须修改寄存器里的参数 / 返回值。具体用法进入函数时修改RDI/X0篡改参数函数返回时修改RAX/X0篡改返回值所有 Frida、Xposed、Inline Hook 都依赖这套规则。