ARM处理器共有37个寄存器,被分为若干个组,这些寄存器包括:
- 31个通用寄存器,包括未分组寄存器R0-R7、分组寄存器R8-R14和程序计数器( PC 指针),均为32位的寄存器。
- 6个状态寄存器,包括程序状态寄存器 CPSR 和5个物理状态寄存器 SPSR (用以异常发生时保存 CPSR 的值,异常退出时恢复 CPSR )。 这些状态寄存器用以标识 CPU 的工作状态及程序的运行状态,均为32位。
具体如下表所示:
用户模式 usr | 系统模式 sys | 特权模式 svc | 中止模式 abt | 未定义指令模式 und | 外部中断模式 irq | 快速中断模式 fiq |
---|---|---|---|---|---|---|
R0 | R0 | R0 | R0 | R0 | R0 | R0 |
R1 | R1 | R1 | R1 | R1 | R1 | R1 |
R2 | R2 | R2 | R2 | R2 | R2 | R2 |
R3 | R3 | R3 | R3 | R3 | R3 | R3 |
R4 | R4 | R4 | R4 | R4 | R4 | R4 |
R5 | R5 | R5 | R5 | R5 | R5 | R5 |
R6 | R6 | R6 | R6 | R6 | R6 | R6 |
R8 | R8 | R8 | R8 | R8 | R8 | R8_fiq |
R9 | R9 | R9 | R9 | R9 | R9 | R9_fiq |
R10 | R10 | R10 | R10 | R10 | R10 | R10_fiq |
R11 | R11 | R11 | R11 | R11 | R11 | R11_fiq |
R12 | R12 | R12 | R12 | R12 | R12 | R12_fiq |
R13(SP) | R13 | R13_svc | R13_abt | R13_und | R13_inq | R13_fiq |
R14(LR) | R14 | R14_svc | R14_abt | R14_und | R14_inq | R14_fiq |
PC(R15) | PC | PC | PC | PC | PC | PC |
CPSR | CPSR | CPSR | CPSR | CPSR | CPSR | CPSR |
SPSR_svc | SPSR_abt | SPSR_und | SPSR_inq | SPSR_fiq |
1. 未分组寄存器 R0 - R7
对于未分组寄存器,它们没有被系统用于特别的用途,因此任何可采用通用寄存器的应用场合都可以使用未分组寄存器。
但需要注意一点,未分组寄存器不会因为处理器模式的改变而更改指向的寄存器,因此在所有的处理器模式下未分组寄存器都指向同一个寄存器,当中断或异常处理造成处理器模式转换的时候,由于不同的处理器模式使用了相同的物理寄存器,这就有可能造成寄存器中的数据被破坏。
2. 分组寄存器 R8 - R14
对于分组寄存器,它们每一次所访问的物理寄存器和处理器当前的运行模式有关。例如在快速中断模式 fiq下R8-R12访问寄存器 R8_fiq-R12_fiq ;而在其他模式下又访问 R8_usr-R12_usr 。因此它们每个对应着两个不同的寄存器。
对于R13(SP)、R14(LR)来说,每个寄存器对应着6个不同的物理寄存器,其中的一个是用户模式与系统模式共用,另外5个物理寄存器对应于其他5种不同的运行模式。采用以下的记号来区分不同的物理寄存器:
R13_< mode >
R14_< mode >
其中,mode为以下几种模式之一:usr、fiq、irq、svc、abt、und。
2.1 R13(SP)
寄存器 R13 在 ARM 指令还有着一个非常重要的作用,通常他被用作堆栈指针,当然这只是一种习惯用法,用户也可以使用其他的寄存器作为堆栈指针,但在Thumb指令集中,某些指令强制性地要求使用R13作为堆栈指针。
由于处理器的每种运行模式均有自己福利的物理寄存器R13,使其指向该运行模式下的栈空间,这样,当程序的运行进入异常模式时,可以将需要保护的寄存器放入R13所指向的堆栈,而当程序从异常模式返回时,则从对应的堆栈恢复,采用这种方式可以保证异常发生后程序的正常执行。
2.2 R14(LR)
R14 也称作子程序连接寄存器(Subroutine Link Register)或连接寄存器 LR 。当执行 BL 子程序调用指令时,R14 中得到 R15 (程序计数器PC)的备份。
|
|
通常情况下,在汇编代码中不会出现 R14 中产生 PC 备份的指令语句。可以简单的理解为在执行调用的同时,将当前 PC 的指向的值 0x00008d70 减去一条指令的长度,这里是ARM工作状态,指令长度为 0x00000004,并交由R14保存。减去一条指令的原因很简单,不减的话返回的时候中间 0x00008d6c 处的那条指令就被跳过了。
(当前执行的是 0x00008d68 处的指令,0x00008d6c 处的指令处于译码阶段,0x00008d70 的指令处于取指阶段,PC总是指向取指阶段的指令。关于 ARM 处理器的流水线机制和 PC 指向的值 详见下文。)其他情况下,R14 也可以用作通用寄存器。与之类似,当发生中断或异常时,对应的分组寄存器 R14_svc、R14_irq、R14_fiq、R14_abt 和 R14_und 用来保存 R15 的返回值。
每一种处理器模式在自己的物理 R14 中存放当前子程序的返回地址。当通过BL、BX 等指令调用子程序时,R14就被设置成该子程序的返回地址。例如有汇编指令如下:
- 执行以下任意一条指令:
|
|
- 在子程序入口处使用以下指令将R14存入堆栈:
|
|
- 对应的,使用以下指令可以完成子程序返回:
|
|
当发生异常中断的时候,该模式下的特定物理R14被设置成该异常模式将要返回的地址。
2.3 R15(PC)
介绍R15之前先简单了解一下 ARM 处理器的是流水线机制。 ARM7 处理器采用3级流水线来增加处理器指令流的速度,能提供 0.9MIPS/MHz 的指令处理速度。
ARM7 的流水线有3个阶段,因此指令分3个阶段执行。
⑴ 取指从存储器装载一条指令
⑵ 译码识别将要被执行的指令
⑶ 执行处理指令并将结果写会寄存器
对于x86处理器来说,只有完成一条指令的读取和执行后,才会执行下一条指令。这样, PC 始终指向的正在“执行”的指令。
而对于 ARM7 来说因为是3级流水线,所以把指令的处理分为了上面所述的3个阶段。所以处理时实际是这样的: ARM 正在执行第1条指令的同时对第2条指令进行译码,并将第3条指令从存储器中取出。因此 ARM7 流水线只有在取第4条指令时,第1条指令才算完成执行。继而 ARM 的 PC 寄存器永远指向当前执行的指令后的第二条指令,即处于取指阶段的指令。
另外,在ARM状态下,最低的两位[1:0]为0,其他位[31:2]用于保存PC;在Thumb状态下,最低位[0]为0,其他位 [31:1]用于保存PC;所以 R15(PC)虽然可以用作通用寄存器,但是有一些指令在使用R15时有一些特殊限制,当违反了这些限制时,程序的执行结果是未知的。
2.4 R16(CPSR)
寄存器R16用作当前程序状态寄存器 CPSR (Current Program Status Register),可在任何运行模式下被访问,它包括条件标志位、中断禁止位、当前处理器模式标志位,以及其他一些相关的控制和状态位。
每一种运行模式下又都有一个专用的物理状态寄存器,称为备份的程序状态寄存器 SPSR (Saved Program Status Register),当异常发生时, SPSR 用于保存 CPSR 的当前值,从异常退出时则可由 SPSR 来恢复 CPSR 。
由于用户模式和系统模式不属于异常模式,他们没有 SPSR ,当在这两种模式下访问 SPSR ,结果是未知的。
2.5 执行条件标志位
ARM 的执行条件与 x86 下面的标志位有些类似,系统通过对这些标志位的判断来确定是否满足执行条件。几乎所有的 ARM 指令都包含一个4位的条件码,位于指令的最高4位。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。
例如,跳转指令 B 可以加上后缀 EQ 变成 BEQ 表示“相同则跳转”,即当 CPSR 中的Z标志置位时发生跳转。在16种条件标志码中,只有15种可以使用,如下表所示。第十六种(1111)为系统保留,暂时不能使用。
编 码 | 条件助记符 | 标志位 | 含 义 |
---|---|---|---|
0000 | EQ | Z=1 | 相等 |
0001 | NE | Z=0 | 不相等 |
0010 | CS | C=1 | 无符号大于或等于 |
0011 | CC | C=0 | 无符号小于 |
0100 | MI | N=1 | 负值 |
0101 | PL | N=0 | 正值或 0 |
0110 | VS | V=1 | 溢出 |
0111 | VC | V=0 | 无溢出 |
1000 | HI | C=1 且 Z=0 | 无符号大于 |
1001 | LS | C=0 且 Z=1 | 无符号小于或等于 |
1010 | GE | N 和 V 相同 | 有符号大于或等于 |
1011 | LT | N 和 V 不相同 | 有符号小于 |
1100 | GT | Z=0 且 N 等于 V | 有符号大于 |
1101 | LE | Z=1 且 N 不等于 V | 有符号小于或等于 |
1110 | AL | 任意 | 无条件执行(不推荐使用) |
1111 | NV | 任意 | 从不执行(不要使用) |