一文教你搞清楚ARM cortex-m3内核的寄存器;
文章目录
- 1 前言
- 2 寄存器全览
- 3 SP
- 4 LR
- 5 PC
- 6 PSR
- 7 中断屏蔽寄存器
- 8 总结
1 前言
本文以ARM的Cortex-M3
内核为例,对于ARM的内核寄存器做一个简单的介绍,并且市面上Cortex-M3比较容易可以买到,可以结合实践加深对ARM汇编的理解。
2 寄存器全览
ARM的寄存器分为通用寄存器和特殊功能寄存器,从R0
—R15
,其中,R0
-R12
都是32位通用寄存器,用于数据操作。绝大多数16位Thumb
指令只能访问R0
-R7
,而32 位Thumb-2 指令可以访问所有寄存器1。 具体如下图所示;
下图是在Keil MDK
的调试环境下的寄存器列表,如下所示;
3 SP
Stack Pointer (SP)
,栈指针寄存器,该寄存器始终保存着一个指向栈顶的值,值得注意的地方;
SP
寄存器的Bit[1:0]
(最低两位)始终为0
,因此这个寄存器是按照字对齐的,也就是四个字节;M3
有两个堆栈指针,并且同一时刻只能使用其中的一个;- 主堆栈指针(
MSP/SP_main
):复位后默认使用的堆栈指针寄存器,用于操作系统内核以及异常处理例程(包括中断服务例程); - 进程堆栈指针(
PSP/SP_process
):由用户的应用程序代码使用。
- 主堆栈指针(
寄存器R13
通常被用作堆栈指针寄存器,另外究竟使用哪个寄存器,由CPU
的控制寄存器来决定;
- Handler mode :即系统发生异常(中断等)的情况会进入该模式,通常使用
SP_main
; - Thread mode:用户程序正常运行时处于该模式,可以选择使用
SP_main
或SP_process
;
CPU
的Configuration Control Register
,如下图所示;
其中Bit[0]
:NONEBASETHRDENA
决定了CPU使用哪一种模式;
4 LR
Link Register (LR)
,连接寄存器,即在调用子程序的时候,可以将当前的程序地址存入LR
寄存器,这样就方便了函数的返回;
通常LR
会配合BL
和BLX
来使用,下面简单举一个函数调用的例子;
BL func01
BL func02
B .
func01
MOV R5, #05
BX LR
func02
MOV R6, #06
BX LR
5 PC
Program Counter(PC)
,程序计数寄存器,这个寄存器的Bit [0]
始终为0
,所以指令的对齐方式是按照四个字节(一个字)或者两个字节(半字)来对齐的。
LDR LR, =func01
LDR PC, =func03
B .
func01
MOV R5, #05
BX LR
func02
MOV R6, #06
BX LR
func03
MOV R7, #07
MOV R8, #08
BX LR
这个程序程序为直接将func03
标签的地址装载到PC
寄存器,因此程序会直接跳转到func03
,因为之前将func01
装载到LR
寄存器,因此最终会调用函数func01
。
6 PSR
程序状态寄存器(Program Status Register
),记录 ALU 标志(0 标志,进位标志,负数标志,溢出标志),执行状态,以及当前正服务的中断号,整体如下图所示;
- APSR:Application PSR;记录 ALU 标志(0 标志,进位标志,负数标志,溢出标志)
- IPSR: Interrupt PSR;正服务的中断号;
- EPSR:Execution PSR;执行状态;
- xPSR:保存状态寄存器;
7 中断屏蔽寄存器
- BASEPRI:禁止所有优先级不高于某个具体数值的中断;
- PRIMASK:禁止所有的中断(除了不可屏蔽中断外
NMI
); - FAULTMASK:禁止所有硬件错误导致的硬件上访中断;
8 总结
从cortex-m3
内核对ARM
架构的寄存器进行初步的了解,包括有哪些寄存器,以及这些寄存器的作用,配合简单的代码,从而加深理解,另外由于笔者能力有限,文中难免存在错误和纰漏,望大佬不吝赐教。
Cortex™-M3 Technical Reference Manual ↩︎