Cortex-M3 R0~R15寄存器组 & 特殊功能寄存器组

【R0~R15寄存器组】

Cortex-M3处理器拥有R0~R15的寄存器组,如:


【R0~R12通用寄存器】
R0~R12都是32位通用寄存器,用于数据操作。其中:

  • R0~R7为低组寄存器,所有的指令都可以访问。
  • R8~R12为高组寄存器,只有32位Thumb2指令和很少的16位Thumb指令能访问。

【R13堆栈指针SP】
Cortex-M3拥有两个堆栈指针,然而它们是banked,任一时刻只能使用其中的一个。

  • 主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理(包括中断服务)。
  • 进程堆栈指针(PSP):由用户的应用程序代码使用。

【R14连接寄存器LR】
连接寄存器LR用于在调用子程序时存储返回地址。例如,在使用BL(分支变连接,Branch and Link)指令时,就自动填充LR的值。

main            ;主程序
    ...
    BL        function1 ; 使用“分支并连接”指令调用function1
                        ; PC=function1,并且LR=main的下一条指令地址
    ...

function1
    ...            ; function1的代码
    BX LR        ; 函数返回(如果function1要使用LR,必须使用前PUSH,
                ; 否则返回时程序就可能跑飞了)

ARM为了减少访问内存的次数(访问内存的操作往往需要3个以上指令周期,带MMU和cache的就更加不确定了),把返回地址直接存储在寄存器中。这样足以使很多只有1级子程序调用的代码无需访问内存(堆栈内存),从而提高了子程序调用的效率。如果多于1级,则需要把前一级的R14值压到堆栈里。
在ARM上编程时,应尽量只使用寄存器保存中间结果,迫不得已才访问内存。
在RISC处理器中,为了强调访问内存操作越过了处理器的界线,并且带来了对性能的不利影响,给它取了一个专业的术语:溅出。

【R15程序计数寄存器PC】
程序计数寄存器PC指向当前的程序地址。如果修改它的值,能改变程序的执行流。

因为Cortex-M3内部使用了指令流水线,读PC时返回的值时当前指令的地址值+4,如:

0x1000:    MOV R0, PC    ; R0 = 0x1004

如果向PC中写数据,就会引起一次程序的分支(但是不更新LR寄存器)。
Cortex-M3中的指令至少是半字(2字节)对齐的,所以PC的LSB总是读回0。然而,在分支时,无论是直接写PC的值还是使用分支指令,都必须保证加载到PC的数值是奇数(即LSB=1),用以表明这是在Thumb状态下执行。如若写了0,则视为企图转入ARM模式,Cortex-M3将产生一个fault异常。


【特殊功能寄存器组】
Cortex-M3中的特殊功能寄存器包括:

  • 程序状态寄存器组(PSRs/xPSR)
  • 中断屏蔽寄存器组(PRIMASK、FAULTMASK以及BASEPRI)
  • 控制寄存器(CONTROL)

它们只能被专用的MSR/MRS指令访问,而且它们也没有与之相关联的访问地址。如:
MRS <gp_reg>, <special_reg> ; 读特殊功能寄存器的值到通用寄存器
MSR <special_reg>, <gp_reg> ; 写通用寄存器的值到特殊功能寄存器

【程序状态寄存器PSRs/xPSR】
程序状态寄存器在其内部又被分为三个子状态寄存器:

  • 应用程序PSR(APSR):
  • 中断号PSR(IPSR):
  • 执行PSR(EPSR):

如:

xPSR:

通过MRS/MSR指令,这3个PSRs即可以单独访问,也可以组合访问(2个组合,3个组合都可以)。

当使用三合一的方式访问时,应使用名字“xPSR”或者“PSR”。

【中断屏蔽寄存器PRIMASK、FAULTMASK、BASEPRI】
中断屏蔽寄存器组(PRIMASK、FAULTMASK以及BASEPRI)用于控制“异常”的使能(enable)和除能(disable)。

  • PRIMASK:这是个只有单一比特的寄存器。当它被置1后,就关掉所有可屏蔽的异常中断,只剩下NMI和硬fault可以响应。它的缺省值为0,表示没有关中断。
  • FAULTMASK:这是个只有单一比特的寄存器。当它被置1后,只有NMI才能响应,所有其他的异常中断包括硬fault都不会响应。它的缺省值为0,表示没有关异常。
  • BASEPRI:这个寄存器最多有9位(由表达优先级的位数决定)。它定义了被屏蔽优先级的阈值。当它被设成某个值后,所有优先级号大于等于此值得中断都被关闭(优先级号越大,优先级越低)。但如果被设为0,则不关闭任何中断。它的缺省值为0。

要访问PRIMASK、FAULTMASK、BASEPRI寄存器,同样需要使用MRS/MSR指令,并且只有在特权级下,才允许访问这3个寄存器。
如:
MRS R0, BASEPRI ; 读取BASEPRI到R0中
MRS R0, FAULTMASK ; 读取FAULTMASK到R0中
MRS R0, PRIMASK ; 读取PRIMASK到R0中
MSR BASEPRI, R0 ; 写入R0到BASEPRI中
MSR FAULTMASK, R0 ;
MSR PRIMASK, R0 ;

** 只有在特权级下,才允许访问这3个寄存器 **

【控制寄存器CONTROL】
控制寄存器有两个用途,其一用于定义特权级别(CONTROL[0]),其二用于选择当前使用哪个堆栈指针(CONTROL[1])。

CONTROL[0]:

  • 0 = 特权级的线程模式
  • 1 = 用户级的线程模式

Handler模式永远都是特权级的。
CONTROL[1]:

  • 0 = 选择主堆栈指针MSP(复位后的缺省值)
  • 1 = 选择进程堆栈指针PSP

Handler模式下只允许使用MSP。

由于Handler模式下用于都是特权级的,且只允许使用MSP;可见这个寄存器主要用于“线程模式”下的设置。

在线程模式下,可设置为特权级的线程模式或非特权级的线程模式;使用MSP或使用PSP。


 参考摘录:《ARM Cortex-M3权威指南.pdf》

原文地址:https://www.cnblogs.com/utank/p/11238218.html