CM3寄存器如图2-4所示。
通用寄存器包括R0~R12。R0~R7也称低组寄存器,它们的字长全为32位。所有指令(包括16位的和32位的)都能访问它们;复位后其初始值是随机的。
R8~R12也称高组寄存器,它们的字长也为32位,16位Thumb指令不能访问它们,而32位Thumb-2指令则不受限制;复位后其初始值也是随机的。
CM3内核中共有两种堆栈指针,支持两种堆栈,分别为进程堆栈和主堆栈,这两种堆栈都指向R13,因此在任何时候,进程堆栈或主堆栈中只有一种是可见的。当引用R13(或写为SP)时,引用的是当前正在使用的那一种,另一种必须用特殊的指令来访问(MRS或MSR指令)。这两种堆栈指针的基本特点如下。
图2-4 CM3寄存器
主堆栈指针(MSP),或者写为SP_main。这是默认的堆栈指针,它由操作系统内核、异常程序代码,以及所有需要特权访问的应用程序代码使用。
进程堆栈指针(PSP),或写为SP_process。它用于不处于异常程序代码中的常规的应用程序代码。
在处理模式和线程模式下,都可以使用MSP,但只有在线程模式才可以使用P SP。
堆栈与CPU工作模式的对应关系如图2-5所示。使用两种堆栈的目的是防止用户堆栈的溢出影响系统核心代码(如操作系统内核)的运行。
图2-5 堆栈与CPU工作模式的对应关系
R14是链接寄存器(LR)。在一个汇编程序中,可以把它写为LR或R14。LR用于在调用子程序时存储返回地址,也用于异常返回。
LR的最低有效位是可读/写的,这是历史遗留的产物。以前,由位0来指示ARM/Thumb状态。因为有些ARM处理器支持ARM和Thumb状态并存,为了方便汇编程序移植,CM3需要允许最低有效位可读/写。
R15是程序计数器(Program Counter),在汇编代码中,一般将其称为PC。因为CM3内部使用了指令流水线,所以读P C时返回的值是当前指令的地址+4。例如:
0x1000:MOV R0,PC;R0=0x1004
如果向PC中写数据,就会引起一次程序的分支(但不更新LR)。因为CM3中的指令至少是半字对齐的,所以P C的最低有效位总是读回0。
程序状态寄存器(PSR)在其内部又被分为3个子状态寄存器,即应用程序状态寄存器(APSR)、中断程序状态寄存器(IPSR)和执行程序状态寄存器(EPSR),如图2-6所示。通过MRS/MSR指令,这3个程序状态寄存器既可以单独访问,又可以组合访问(2个组合或3个组合都可以)。当使用三合一的方式访问时,应使用名字“xP SR”或“P SR”,如图2-7所示。程序状态寄存器各位域定义如表2-2所示。
图2-6 CM3中的程序状态寄存器
图2-7 合体后的程序状态寄存器(xPSR)
表2-2 程序状态寄存器各位域定义
续表
异常中断寄存器的功能描述如表2-3所示。
表2-3 异常中断寄存器的功能描述
控制寄存器有两个用途,即定义权限和选择当前使用的堆栈指针,由两个位来行使这两个职能,如表2-4所示。
表2-4 CM3的控制寄存器
因为处理模式永远都是特权级的,所以CONTROL [0]位仅对线程模式有效。仅在特权级下操作时,才允许写CONTROL[0]位。一旦进入用户级,唯一返回特权级的途径就是先触发一个(软)中断,再由服务例程改写该位。
在CM3的处理模式中,CONTROL [1]位总为0;而在线程模式中则可以为0或1。因此,仅当处于特权级的线程模式下时,此位才可写,其他场合下禁止写此位。
CPU的工作模式、堆栈、控制寄存器之间的关系如表2-5所示。
表2-5 CPU的工作模式、堆栈、控制寄存器之间的关系
CM3寄存器总结如表2-6所示。
表2-6 CM3寄存器总结