ARM寄存器

官方文档(Contex-M7):https://developer.arm.com/documentation/dui0646/c/The-Cortex-M7-Processor/Programmers-model/Core-registers

核心寄存器

以下为处理器核心寄存器

image-20230927200317758

按照寄存器的作用大致可以这样进行分类

R0-R12通用寄存器
SP(R13) /PSP/MSP堆栈指针
LR(R14)链接寄存器
PC(R15)程序计数器
PSR程序状态寄存器
PRIMASK异常掩码寄存器1
FAULTMASK异常掩码寄存器2
BASEPR异常掩码寄存器3
CONTROL控制寄存器

接着给出了一张表

image-20230927201537433

在程序执行过程中,特别是在线程模式(Thread mode)和处理器模式(Handler mode)下,对寄存器的访问类型。在这两种模式下,处理器可以以不同的权限级别运行,这会影响到可以访问哪些系统资源和寄存器。此外,“Debug access can differ”意味着在调试模式下,访问类型可能会有所不同,可能会允许访问更多的寄存器或资源。

如果寄存器的访问级别条目标记为“Either”,则意味着无论是具有特权的还是非特权的软件都可以访问该寄存器。在ARM架构中,特权软件通常可以访问更多的系统资源和寄存器,而非特权软件的访问权限会受到更多的限制。如果一个寄存器可以被“Either”访问,那么它可以被运行在不同权限级别的软件访问,这包括在操作系统内核中运行的代码(特权)和用户空间应用程序(非特权)。

知识点补充:

ARM Cortex-M7运行模式

ARM Cortex-M7,像其他Cortex-M系列处理器一样,主要运行在两种模式下:

1. 线程模式(Thread Mode)

  • 在这种模式下,处理器执行应用程序代码。
  • 这是处理器复位后的默认模式。
  • 在线程模式下,代码可以运行在特权级别或非特权级别。
  • 特权级别允许代码执行一些特权指令,并访问特权资源,例如系统控制寄存器。
  • 非特权级别限制了对某些资源和指令的访问,以提供更高的系统安全性。

2. 处理模式(Handler Mode)

  • 在这种模式下,处理器执行异常处理程序,例如中断服务例程(ISR)。
  • 处理模式总是在特权级别运行。
  • 当异常发生时,处理器会自动切换到处理模式,并开始执行相应的异常处理程序。
  • 一旦异常处理完成,处理器会返回到线程模式,并继续执行被中断的程序。

3. 调试模式(Debug Mode)

  • 虽然不是执行模式,但调试模式允许开发者在开发和调试过程中访问处理器的内部状态。
  • 在调试模式下,可以访问和修改寄存器的值,单步执行代码等。

在Cortex-M7的设计中,这些模式帮助实现了代码的隔离和安全执行,允许系统以不同的权限级别运行代码,以满足实时和嵌入式应用的需求。

1. 通用寄存器(R0-R12)

Cortex-M系列处理器通常有一组通用寄存器,通常标记为R0到R12。这些寄存器主要用于存储临时数据。

image-20230927203632486

2.堆栈指针SP(R13)

image-20230927203955375

栈指针用于跟踪栈的顶部,栈是一种数据结构,用于存储局部变量、函数参数、返回地址等。

在线程模式(Thread Mode)中,CONTROL寄存器的bit[1]决定了要使用哪个栈指针:

  • 如果bit[1]为0,则使用主栈指针(Main Stack Pointer,MSP)。
  • 如果bit[1]为1,则使用进程栈指针(Process Stack Pointer,PSP)。

MSP和PSP的区别:

  • MSP:通常用于操作系统内核和中断服务例程(ISR),是复位后的默认栈指针。
  • PSP:通常用于用户任务或线程,允许每个任务或线程有其自己的栈空间。

简单点理解使用裸机CONTROL的bit[1]设置为0,使用操作系统CONTROL的bit[1]设置为1

复位时的行为:

当处理器复位时,处理器会从地址0x00000000加载MSP的值。这个地址通常包含一个值,该值是栈的起始地址,也就是栈底。这个地址是实现定义的,意味着它依赖于具体的处理器实现和硬件设计。

3.链接寄存器LR(R14)

image-20230927205413361

主要用于存储子程序、函数调用和异常的返回信息。下面是对LR的一些详细解释:

存储返回信息:

  • 当一个函数或子程序被调用时,处理器会将下一条指令的地址(即返回地址)存储在LR中。这样,当函数或子程序执行完毕后,处理器可以通过LR中的地址返回到调用者。
  • 例如,如果有一个函数调用如下:main -> functionA,那么当functionA被调用时,LR会存储functionA之后的那条指令的地址,以便functionA执行完毕后返回到main

异常和中断:

  • 当发生异常或中断时,处理器也会将下一条指令的地址存储在LR中,以便在异常处理或中断服务例程(ISR)执行完毕后返回到被中断的位置继续执行。

复位时的LR值:

  • 当处理器复位时,LR的值会被设置为0xFFFFFFFF。这是一个无效的地址值,用于指示处理器刚刚经历了复位,还没有任何有效的返回地址存储在LR中。

总结:

Link Register(LR)是ARM架构中用于存储返回地址的寄存器,无论是函数调用还是异常处理,都会利用LR来存储返回地址,以便在执行完毕后返回到正确的位置继续执行。而在处理器复位时,LR会被初始化为一个无效的地址值0xFFFFFFFF

4.程序计数器PC(R15)

image-20230927210336697

程序计数器(PC):

  • PC存储着当前正在执行的程序地址,即下一条要执行的指令的地址。
  • 在程序执行过程中,PC会逐步递增,指向下一条要执行的指令,除非遇到跳转指令,此时PC会被设置为跳转目标的地址。
  1. 复位时的行为:
  • 当处理器复位时,PC会被加载为复位向量的值。复位向量是Vector Table Offset Register(VTOR)的初始值加上0x00000004
  • VTOR是向量表偏移寄存器,存储着异常向量表的起始地址。异常向量表包含了各种异常和中断的处理程序的入口地址。
  • 因此,复位时,PC的值会被设置为异常向量表中复位向量的值,这通常是复位处理程序的入口地址。
  1. EPSR T-bit:
  • 在复位时,加载到PC的值的bit[0]会被加载到EPSR(Execution Program Status Register,执行程序状态寄存器)的T-bit中,并且必须为1。
  • T-bit用于指示处理器当前是处于Thumb指令集状态还是ARM指令集状态。在Cortex-M系列处理器中,只支持Thumb指令集,因此T-bit必须为1。

总结:

简言之,PC寄存器存储着当前要执行的指令的地址。当处理器复位时,PC会被设置为复位向量的值,即复位处理程序的入口地址,而T-bit会被设置为1,指示处理器使用Thumb指令集。

程序状态寄存器PSR(内容较多)

image-20230927211149465

image-20230927211211442

image-20230927213555181

Program Status Register(PSR)是一个复合寄存器,它结合了以下三个状态寄存器:

  • Application Program Status Register (APSR) 应用程序状态寄存器
  • Interrupt Program Status Register (IPSR) 中断程序状态寄存器
  • Execution Program Status Register (EPSR) 执行程序状态寄存器

这些寄存器在32位的PSR中是互斥的位域。

这个表格描述了Program Status Register(PSR)的不同组合和它们的属性。下面是对表格内容的解释:

1. PSR:

  • 类型: RWa, b(可读写)
  • 组合: APSR, EPSR, 和 IPSR
  • 说明:

    • a. 处理器会忽略对IPSR位的写入。
    • b. 读取EPSR位会返回零,处理器也会忽略对这些位的写入。

2. IEPSR:

  • 类型: ROb(只读)
  • 组合: EPSR 和 IPSR
  • 说明: 这个组合只包含EPSR和IPSR的信息,且是只读的。

3. IAPSR:

  • 类型: RWa(可读写)
  • 组合: APSR 和 IPSR
  • 说明:

    • a. 处理器会忽略对IPSR位的写入。

4. EAPSR:

  • 类型: RWb(可读写)
  • 组合: APSR 和 EPSR
  • 说明:

    • b. 读取EPSR位会返回零,处理器也会忽略对这些位的写入。

总结:

  • PSR 是一个集合了APSR、EPSR和IPSR的可读写寄存器,但对IPSR的写入和对EPSR的读写会被忽略。
  • IEPSR 是一个集合了EPSR和IPSR的只读寄存器。
  • IAPSR 是一个集合了APSR和IPSR的可读写寄存器,但对IPSR的写入会被忽略。
  • EAPSR 是一个集合了APSR和EPSR的可读写寄存器,但对EPSR的读写会被忽略。

这些组合允许开发者以不同的方式访问和操作PSR寄存器中的特定部分。

1. APSR(Application Program Status Register):

image-20230927212706590

1. NZCVQ 标志位

  • N (Negative/Minus Flag):当最后一条执行的指令的结果为负数时,该位被设置。
  • Z (Zero Flag):当最后一条执行的指令的结果为零时,该位被设置。
  • C (Carry Flag):用于表示无符号数学运算中的进位或借位。例如,在加法中,如果结果产生进位,则该位被设置。
  • V (Overflow Flag):用于表示有符号数学运算中的溢出。例如,在加法中,如果两个正数的和超过了最大正数的范围,产生溢出,则该位被设置。
  • Q (Saturation Flag):用于 SIMD(Single Instruction, Multiple Data)指令。当 SIMD 操作产生饱和时,该位被设置。

SIMD(Single Instruction, Multiple Data)指令是一种允许单一指令对多个数据元素进行操作的并行计算技术

2. GE (Greater than or Equal flags) 标志位

  • GE[3:0]

    :这四个位用于 SIMD 指令,存储并行比较操作的结果。

    • GE[0]:存储第一对数据元素的比较结果。
    • GE[1]:存储第二对数据元素的比较结果。
    • GE[2]:存储第三对数据元素的比较结果。
    • GE[3]:存储第四对数据元素的比较结果。

使用场景

  • NZCV:这些标志位通常用于条件分支指令,以决定程序的执行流程。例如,一条条件跳转指令可能会检查 Z 位,如果 Z 位被设置(即上一条指令的结果为零),则执行跳转。
  • Q:在执行 SIMD 指令时,如果某个操作数超出了目标数据类型的范围,会发生饱和,此时 Q 位会被设置。
  • GE[3:0]:这些位用于优化 SIMD 和媒体指令的性能,允许程序在执行并行操作时更加灵活地处理各个数据元素的比较结果。

2. IPSR(Interrupt Program Status Register):

image-20230927212756340

  • 存储着当前正在处理的异常的编号(ISR_NUMBER)。
  • 当没有异常正在处理时,IPSR的值为0。

3. EPSR(Execution Program Status Register):

image-20230927212826962

image-20230927212844133

  • 包含了一些执行状态信息,例如ICI/IT用于存储Thumb状态下的IT(If-Then)状态和Java状态,T位用于指示当前的指令集状态(Thumb/ARM)。
  • 在Cortex-M系列处理器中,EPSR的大部分位都是保留的,并且在执行MRS指令时读取EPSR会得到0。
  • 可以使用MSR(Move to Special Register)和MRS(Move from Special Register)指令来访问这些寄存器。
  • 可以单独访问这些寄存器,也可以组合访问任意两个或所有三个寄存器。
  • 例如,使用MRS指令和PSR参数可以读取所有的寄存器,使用MSR指令和APSR_nzcvq参数可以写入APSR的N, Z, C, V, 和Q位。
如果觉得我的文章对你有用,请随意赞赏