ARM寄存器
寄存器是存在于CPU中的存储速度极快的存储器(速度: 寄存器>cache>内存>外存flash),主要负责储存程序运行过程中需要保存的临时变量和系统环境变量等等.
arm寄存器的分类
在32-bit的ARM Cortex-A8处理器中的寄存器相应的也是32位的.如下图
其中一共有40个32-bit的寄存器:
1. 32个通用寄存器;
2. 7个状态寄存器:(state program status register)
- 1个CPSR(Current Program State Register,储存当前程序的状态): CPSR包含条件码标志,中断禁止位,当前处理器模式以及其他状态和控制信息。
- 6个SPSR(Saved Program State Register,保存的程序运行状态): 以便异常返回后恢复异常发生时的工作状态。
3.1个程序计数器PC(r15 Program Counter)
用于存放下一条指令所在单元的地址的地方
当执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中(取指)。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。
分组寄存器/未分组寄存器
通用寄存器中需要特别注意的是:还有一个分组的概念:
- 未分组寄存器R0-R7
在任何模式下都是通用的;访问的都是同一个物理寄存器. - 分组寄存器R8-R14
这部分之所以叫”分组寄存器”,是因为当在不同的模式下(尤其是在FIQ模式下),它们访问的寄存器在物理上不是同一个,这样的设计也是为了让FIQ模式能够实现FAST Interruption, 这样独享一部分寄存器,在中断到来时就可以不用保存寄存器的当前状态,直接使用独有的寄存器完成FAST,因此FIQ也多用来时间紧急的任务,如DMA处理.
R13/R14堆栈指针和链接寄存器
比较特殊的是r13,r14:
R13:SP
r13(sp):Stack Pointer:堆栈指针.
每种异常都有自己的R13,异常处理程序负责初始化自己的SP, 使其指向该异常模式专用的栈顶地址.也就是说,每种异常模式都有自己独有的堆栈指针(除了user/sys模式公用外), 这样ARM可以访问六个不同的堆栈空间;
在异常处理程序入口,首先把将会用到的(可能会被破坏的)其他寄存器的值保存到堆栈中(压栈),返回时,再把这些保存的值加载对应的寄存器,恢复现场,从而实现保护现场的目的.
为了更准确地描述堆栈,根据“压栈”操作时堆栈指针的增减方向,将堆栈区分为‘递增堆栈’(SP 向大数值方向变化)和‘递减堆栈’(SP 向小数值方向变化);又根据SP 指针指向的存储单元是否含有堆栈数据,又将堆栈区分为‘满堆栈’(SP 指向单元含有堆栈有效数据)和‘空堆栈’(SP 指向单元不含有堆栈有效数据)。
这样两两组合共有四种堆栈方式——满递增、空递增、满递减和空递减。
ARM处理器中的R13被用作SP。当不使用堆栈时,R13 也可以用做通用数据寄存器。
R14: LR
r14(LR):Link Register: 链接寄存器
每种处理器模式都有自己的R14,用来存放当前子程序的返回地址.当通过BL或BLX指令调用子程序时,R14被设置为该子程序返回的地址. 所以,当子程序完成返回时,重新将R14的值–>PC,使得程序能够继续之前的程序向下继续执行.
典型的处理方式:
①. 执行如下任何一条均可:
MOV PC, LR
BX LR
②. 在子程序的入口使用如下指令将PC保存到堆栈(压栈)
STMFD SP!, {[R0-R12], LR} @push
然后在子程序返回时,恢复
LDMFD SP!, {<对应的寄存器>, PC} @pop