为何Arm64会使用x8-x17寄存器传递函数参数?
Arm64 Android 11 中 x8-x15 寄存器用于参数传递的原因
你观察到的现象并非违反Arm官方的AAPCS64规范,而是Android平台编译器优化及调用约定变体导致的,具体原因如下:
Android Clang 编译器的性能优化:
Android基于AAPCS64规范做了实用化扩展,Clang编译器在编译优化开启(如-O2及以上)时,会利用x8-x15这类临时寄存器传递超出x0-x7数量的参数,以此减少栈操作开销、提升执行效率。这类寄存器属于调用方无需保留的临时寄存器,并非AAPCS64规定的标准参数传递寄存器,本质是编译器的优化行为。特殊参数类型的对齐需求:
若参数包含需要严格对齐的类型(如128位向量、大尺寸结构体),编译器会优先选择寄存器传递以规避栈对齐的性能损耗。你的测试代码中body、dataHeader这类复杂类型指针可能触发了该逻辑。调试场景的临时值误解:
调试时看到的x8-x15寄存器值,可能是调用方准备参数过程中的临时存储,而非直接传递给函数的参数。进入函数内部后,超出8个的参数仍会从栈中读取,可通过查看函数汇编代码验证这一点——观察函数是否从栈指针偏移处加载第9个及以后的参数。
验证方法
- 查看编译生成的汇编代码(使用
objdump -d或Android Studio反编译功能),确认参数实际传递路径:前8个参数是否用x0-x7,后续参数是否入栈。 - 关闭编译器优化(添加
-O0编译选项),此时编译器会严格遵循基础AAPCS64规范,x8-x15将不再用于参数传递。
内容的提问来源于stack exchange,提问作者xxking
相关产品推荐
相关产品推荐

