1. ARM与Thumb过程调用标准深度解析
在嵌入式系统开发中,函数调用约定是确保不同编译单元之间正确交互的基础协议。ARM架构下的过程调用标准(Procedure Call Standard,简称PCS)定义了函数调用时寄存器使用规则、参数传递方式和栈帧管理机制,是编译器与汇编程序间的重要契约。本文将深入剖析ARM模式下的APCS(ARM Procedure Call Standard)和Thumb模式下的TPCS(Thumb Procedure Call Standard),揭示其设计原理和实际应用中的关键细节。
提示:过程调用标准不仅是编译器开发者的关注点,对于需要进行底层调试、性能优化或混合语言开发的工程师同样至关重要。理解这些规范能帮助开发者分析栈溢出问题、优化函数调用开销,以及处理跨模块的二进制接口问题。
1.1 寄存器角色定义与使用规范
1.1.1 ARM模式寄存器分工
在APCS标准中,ARM处理器的16个寄存器被赋予特定的角色:
| 寄存器 | APCS名称 | 核心用途 | 调用保存要求 |
|---|---|---|---|
| R0 | a1 | 第一个参数/返回值 | 调用者保存 |
| R1 | a2 | 第二个参数/辅助返回值 | 调用者保存 |
| R2 | a3 | 第三个参数 | 调用者保存 |
| R3 | a4 | 第四个参数 | 调用者保存 |
| R4-R7 | v1-v4 | 局部变量寄存器 | 被调用者保存 |
| R8 | v5 | 附加局部变量寄存器 | 被调用者保存 |
| R9 | v6/sb | 静态基址寄存器或附加变量寄存器 | 视情况而定 |
| R10 | v7/sl | 栈限制寄存器 | 被调用者保存 |
| R11 | fp | 帧指针 | 被调用者保存 |
| R12 | ip | 临时工作寄存器 | 调用者保存 |
| R13 | sp | 栈指针 | 必须保持对齐 |
| R14 | lr | 链接寄存器(返回地址) | 调用者保存 |
| R15 | pc | 程序计数器 | 由分支指令自动维护 |
在函数调用边界,寄存器保存遵循"被调用者保存"(callee-saved)和"调用者保存"(caller-saved)的混合策略。具体来说:
- 参数寄存器a1-a4和临时寄存器ip由调用者负责保存
- 变量寄存器v1-v7、帧指针fp和栈限制寄存器sl由被调用函数负责保存
- 链接寄存器lr在非叶函数中必须由被调用者保存
1.1.2 Thumb模式的特殊约定
Thumb指令集作为ARM的16位压缩指令集,其TPCS标准在寄存器使用上有显著差异:
- 寄存器可见性:Thumb状
