ARM 架构中,R13栈指针(SP)是什么?
本文来自于我关于 Arm Cortex-M 编程模型的系列文章。欢迎阅读、点评与交流~
1、Arm Cortex-M 处理器的编程模型
2、ARM 架构中,R13栈指针(SP)是什么?
R13 是 ARM 架构中的栈指针寄存器,通常也直接被称为 SP。
核心概念
-
物理寄存器:在 ARM 中,R13 是16个通用寄存器(R0-R15)中的一个,被专门设计用作栈指针。
-
别名 :在大多数 ARM 汇编器和文档中,你更常看到的是它的别名 SP,而不是 R13。
-
作用 :SP 指向当前栈的顶部位置,用于:
- 函数调用时的参数传递和返回地址保存
- 局部变量的存储
- 寄存器保存(函数调用前后的现场保护)
- 中断/异常处理
关键特性
1. 栈增长方向
- ARM 通常使用满递减栈(Full Descending, FD)
- 栈向内存地址减小方向增长
- 入栈时:先减 SP,再存储数据
- 出栈时:先读取数据,再加 SP
2. 操作示例
assembly
PUSH {R0, R1} ; 等价于 STMDB SP!, {R0, R1}
; 1. SP = SP - 8 (两个寄存器)
; 2. 将 R0, R1 存储到栈中
POP {R0, R1} ; 等价于 LDMIA SP!, {R0, R1}
; 1. 从栈中读取数据到 R0, R1
; 2. SP = SP + 8
3. 处理器模式下的不同 SP
在某些 ARM 处理器模式中,有多个独立的栈指针:
- SP_usr - 用户模式栈指针
- SP_svc - 管理模式(用于 SWI、复位等)
- SP_abt - 中止模式
- SP_und - 未定义指令模式
- SP_irq - IRQ 中断模式
- SP_fiq - FIQ 快速中断模式
这允许不同模式有独立的栈空间,提高系统可靠性。
实际使用注意事项
-
对齐要求:
- ARMv7-A/R:SP 必须保持 8 字节对齐
- ARMv6 及之前:4 字节对齐
- 某些浮点/NEON 操作需要 16 字节对齐
-
初始化:
assembly
; 系统启动时需要初始化 SP
LDR SP, =0x20008000 ; 设置栈顶地址
- 函数调用约定 :
- AAPCS(ARM 过程调用标准)规定了 SP 的使用规则
- 函数必须保持栈平衡
- SP 在函数入口和出口必须对齐
在 C 语言中的体现
c
// 局部变量存储在栈中
void func(void) {
int x = 10; // x 存储在栈上,位置由 SP 决定
char buffer[64]; // buffer 也在栈上
}
总结
R13/SP 是 ARM 架构中管理栈内存的关键寄存器,它:
- 指向当前栈顶
- 自动调整以分配/释放栈空间
- 支持不同处理器模式的独立栈
- 是函数调用、局部变量和异常处理的基础
理解 SP 对于 ARM 汇编编程、嵌入式系统开发和调试至关重要。