Cortex-M3处理器的寄存器包括R0~R15和一些特殊的寄存器。其中R0到R12是通用寄存器,但是一些16位的Thumb指令只能访问R0到R7(低寄存器),而32位的Thumb-2指令则可以访问所有这些寄存器。特殊寄存器只能通过特殊访问指令访问。

文章目录

  • 1 核心寄存器
    • 1.1 R13(Stack Pointer):MSP和PSP
    • 1.2 R14(Link Register)
    • 1.3 R15(Program Counter)
  • 2 特殊寄存器
    • 2.1 Program Status Register
    • 2.2 PRIMASK, FAULTMASK, and BASEPRI Registers
    • 2.3 Control Register

所有的寄存器如下图所示:

1 核心寄存器

AAPCS(ARM Architecture Procedure Calling Standard)定义的寄存器如下:

寄存器 别名 描述
r15 PC Program Counter(Current Instruction)
r14 LR Link Register(Return Address)
r13 SP Stack Pointer
r12 IP Intra-Procedure-call scratch register
r11 v8 Variable-register 8
r10 v7 Variable-register 7
r9 v6,SB,TR Variable-register 6 or Platform Register
r8~r4 v5~v1 Variable-register 5 ~ Variable-register 1
r3~r0 a4~a1 Argument/scratch register 4 ~ Argument/scratch register 1

这里主要介绍R13~R15寄存器

1.1 R13(Stack Pointer):MSP和PSP

R13是堆栈指针,在CM3中,有两个独立的堆栈内存,用户只能访问当前的堆栈,如果要访问另一个需要用特殊寄存器的MRSMSR指令来进行操作。两种堆栈分别为:

  • MSP(Main Stack Pointer):默认的SP,用在操作系统内核、异常处理函数和所有需要优先权限的访问
  • PSP(Process Stack Pointer):通常由运行嵌入式操作系统的系统中的线程进程使用(不处于异常处理程序中时)

并不是两个堆栈都必须同时使用,对于简单的应用来说,只需要用到MSP。对于堆栈的访问需要用PUSHPOP指令。

PUSH {R0} ; R13=R13-4, then Memory[R13] = R0
POP {R0}  ; R0 = Memory[R13], then R13 = R13 + 4

PUSHPOP通常用于在子例程开始时将寄存器内容保存到堆栈内存中,然后在子例程结束时从堆栈中恢复寄存器。

subroutine_1PUSH {R0-R7, R12, R14} ; Save registers...                    ; Do your processingPOP {R0-R7, R12, R14}  ; Restore registersBX R14                 ; Return to calling function

因为寄存器PUSHPOP操作总是按字对齐的(地址必须是0x0, 0x4, 0x8, …),故SP/R13的低两位被硬件拉低,读取它将总是为0。

1.2 R14(Link Register)

LR用于在调用函数时,保存它下一条指令的PC。

main ; Main program
...
BL function1    ; Call function1 using Branch with Link instruction.; PC = function1 and; LR = the next instruction in main
...
function1
...             ; Program code for function 1
BX LR           ; Return

尽管PC的第0位总是为0(指令是按字或半字对齐的),但LR寄存器的第0位是可读写的,这是因为在Thumb指令集中,第0位用来指示ARM/Thumb状态。为了允许Thumb-2的程序能在其它支持Thumb-2的ARM处理器中运行,所以LSB是可读写的。

1.3 R15(Program Counter)

由于Cortex-M3处理器的流水线特性,当读取PC时,该值与此时正在执行指令的地址通常会相差4。例如:

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

其他的指令,比如load指令,由于地址计算中的对齐,PC的有效值可能不是指令地址加4。但是在执行过程中,PC值仍然比指令地址提前至少2个字节。

直接向PC写入数值将触发一个跳转指令,但是LR寄存器不会更新。但无论是直接向PC写入值还是使用B/BL/BX等跳转指令,目标地址的LSB都应该设置为1,表示这是一个Thumb state操作。如果为0,尝试切换到ARM state则会触发异常。

2 特殊寄存器

Cortex-M3中的特殊寄存器如下:

  • Program Status registers (PSRs)
  • Interrupt Mask registers (PRIMASK, FAULTMASK, and BASEPRI)
  • Control register (CONTROL)

特殊寄存器只能通过MSRMRS指令访问,它们没有内存地址:

MRS <reg>, <special_reg>  ; Read special register
MSR <special_reg>, <reg>  ; write to special register

2.1 Program Status Register

程序状态寄存器PSRs被分为三个状态寄存器:

  • Application Program Status register (APSR)
  • Interrupt Program Status register (IPSR)
  • Execution Program Status register (EPSR)

这三个寄存器可以被同时访问,使用xPSR关键字表示这三个寄存器。下图所示为寄存器中具体的字段,还有ARM和ARM7 TDMI中xPSR的对比:

这些位的定义如下所示:

Bit Decription
N Negative
Z Zero
C Carry/borrow
V Overflow
Q Sticky saturation flag
ICI/IT Interrupt-Continuable Instruction (ICI) bits, IF-THEN instruction status bit
T Thumb state, always 1; trying to clear this bit will cause a fault exception
Exception number Indicates which exception the processor is handling

其中APSR是可读写的,而IPSREPSR是只读的。

MRS r0, APSR   ; Read Flag state into R0
MRS r0, IPSR   ; Read Exception/Interrupt state
MRS r0, EPSR   ; Read Execution state
MSR APSR, r0   ; Write Flag stateMRS r0, PSR    ; Read the combined program status word
MSR PSR, r0    ; Write combined program state word

2.2 PRIMASK, FAULTMASK, and BASEPRI Registers

PRIMASKFAULTMASKBASEPRI用来关闭异常。

Register Name Description
PRIMASK 仅1位。当为1时,表示允许NMIHard fault异常,而其它所有的中断和异常都会被屏蔽。默认值为0。
FAULTMASK 仅1位。当为1时,表示仅允许NMI异常,其它所有中断和错误处理异常都会被屏蔽。默认值为0。
BASEPRI 最多8位(取决于芯片应用的优先级位数)。它表示屏蔽优先级的等级,它将屏蔽所有比该优先级相同和更低的中断。默认值为0。
  • PRIMASKBASEPRI寄存器对于在对实时要求高的任务中,用来临时禁用中断非常有用
  • 而当任务崩溃时,可能会发生许多不同的错误,操作系统可以使用FAULTMASK临时禁用异常错误处理程序,这样在内核开始清理这些错误时,不会被其它错误所中断。因此,FAULTMASK为OS内核提供了处理错误条件的时间。

为了访问这些寄存器,芯片厂商CMSIS一般会在设备的驱动库中提供相应的C函数API:

x = __get_BASEPRI();   // Read BASEPRI register
x = __get_PRIMARK();   // Read PRIMASK register
x = __get_FAULTMASK(); // Read FAULTMASK register
__set_BASEPRI(x);      // Set new value for BASEPRI
__set_PRIMASK(x);      // Set new value for PRIMASK
__set_FAULTMASK(x);    // Set new value for FAULTMASK
__disable_irq();       // Clear PRIMASK, enable IRQ
__enable_irq();        // Set PRIMASK, disable IRQ

__get_BASEPRI()为例,其实现为:

__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
{uint32_t result;__ASM volatile ("MRS %0, basepri" : "=r" (result) );return(result);
}

当然在汇编中,我们可以直接通过MRSMSR来访问:

MRS r0, BASEPRI    ; Read BASEPRI register into R0
MRS r0, PRIMASK    ; Read PRIMASK register into R0
MRS r0, FAULTMASK  ; Read FAULTMASK register into R0
MSR BASEPRI, r0    ; Write R0 into BASEPRI register
MSR PRIMASK, r0    ; Write R0 into PRIMASK register
MSR FAULTMASK, r0  ; Write R0 into FAULTMASK register

注意,这三个寄存器不能再user mode下被更改。

2.3 Control Register

控制寄存器用于定义privilege levelSP的选择。我们暂时关注该寄存器的低2位:

Bit Function
1 Stack status
1 = Alternate stack is used
0 = Default stack(MSP) is used
thread mode下,Alternate stack为PSP,在handler mode下没有Alternate stack,该位必须设置为0
0 0 = Privileged in thread mode
1 = User state in thread mode
handler mode下,总是处于privilege mode

对于bit0来说,只有当内核处于thread mode并具有privilege时,该位才可写。在user statehandler mode下,不允许写入此位。除了写入这个寄存器之外,改变这个位的另一种方法是在异常返回时改变LR的第2位。

  • user state切换回privilege state的唯一方法是触发中断并在异常处理程序中更改此状态。

同样的,CMSIS提供了C函数来访问这个寄存器,当然我们也可以使用汇编来访问。

x = __get_CONTROL(); // Read the current value of CONTROL
__set_CONTROL(x);    // Set the CONTROL value to x
MRS r0, CONTROL      ; Read CONTROL register into R0
MSR CONTROL, r0      ; Write R0 into CONTROL register

ARM基础(1):Cortex-M3的核心寄存器和特殊寄存器相关推荐

  1. Cortex M3内核架构

    CortexM3内核架构 宗旨:技术的学习是有限的,分享的精神是无限的. 1.ARMCortex-M3处理器 Cortex-M3处理器内核是单片机的中央处理单元( CPU). 完整的基于CM3的MCU ...

  2. Cortex、ARMv8、arm架构、ARM指令集、soc?Cortex A8、A9都是ARMv7a 架构;Cortex M3、M4是ARMv7m架构;前者是处理器(内核)后者是指令集的架构(架构)

    架构组成元素的指令集状态或者语法thumb指令集与arm指令集的区别例如thumb指令集是什么_thumb指令集与arm指令集的区别以及thumb-2的关系在下一文中介绍,本文暂时不讨论 有粉丝问我到 ...

  3. ARM和英特尔的386系列内存管理MMU硬件机制不同,ARM是基于协处理CP15(核心是C2 TTRB0,1)分页式,386是以段寄存器和CR3寄存器分段分页式内存管理

    ARM和英特尔的386系列内存管理MMU硬件机制不同,ARM是基于协处理CP15(核心是C2 TTRB0,1)分页式,386是以段寄存器和CR3寄存器分段分页式内存管理

  4. ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 有啥区别

    ARM架构.ARM7.ARM9.STM32.Cortex M3 M4.51.AVR之间有什么区别和联系? ARM架构:由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~AR ...

  5. ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?

    本文转自嵌入式资讯精选公众号,特别鸣谢, 编者按:初学习ARM单片机的同学们可能会对ARM的架构定义并不是很明确,形形色色的名词背后到底代表什么含义呢?请听听这位嵌入式工程师的经验总结. ARM架构: ...

  6. ARM 架构 ARM7 ARM9 STM32 Cortex M3 M4 51 AVR 有啥区别

    ARM架构.ARM7.ARM9.STM32.Cortex M3 M4.51.AVR之间有什么区别和联系? ARM架构:由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~AR ...

  7. ARM Cortex M3指令集

    一.跳转指令 跳转指令用于实现程序流程的跳转,在ARM 程序中有两种方法可以实现程序流程的跳转: Ⅰ.使用专门的跳转指令. Ⅱ.直接向程序计数器PC 写入跳转地址值. 通过向程序计数器PC 写入跳转地 ...

  8. ARM基础教程 | ARM、Cortex-M与ARMv8-M什么关系?

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | 嵌入式专栏 我们使用的处理器都有一套架构,比如intel 酷睿 i5 属于X86架构,再比如STM32F0是Co ...

  9. ARM基础教程 1 | ARM、Cortex-M与ARMv8-M

    ARM基础教程 | ARM.Cortex-M与ARMv8-M什么关系? 目录 ARM架构 Cortex-M内核 ARMv8-M架构 我们使用的处理器都有一套架构,比如intel 酷睿 i5 属于X86 ...

最新文章

  1. fastadmin弹框提示不起作用 confirm
  2. 查看mysql 默认端口号和修改端口号
  3. c语言中读取内存的文件,c++从内存中读取文件内容,内容写到内存 实现文件的内存共享代码实例...
  4. 【渝粤教育】广东开放大学 行政管理 形成性考核 (35)
  5. 为革命,保护视力——为Eclipse更换暗黑皮肤及编辑页面的字体颜色主题
  6. sql plus 表的总记录数是多少_直播回顾 | 亿级并发丝毫不虚,TDSQL-SQL引擎是如何炼成的...
  7. Java GC机制详解
  8. 1909升级卡64_Win10专业版下载_1909 版64位(2019年11月更新)
  9. oracle考试试题及其答案,oracle考试试题及答案
  10. 《学习笔记13》——web前端助手:插件fehelper的使用
  11. Python数据处理Tips数据预处理操作方法汇总
  12. 千兆以太网在国产FPGA(智多晶)上的实现
  13. MTK Pump Express 快速充电原理分析
  14. etc fstab 详解linux,/etc/fstab功能详解
  15. Oracle数据库的锁类型
  16. 转载-中文文案排版指指南
  17. 04-05赛季欧洲冠军杯决赛.AC milan vs Liverpool
  18. LDAP添加 memberOf 模块
  19. 工业机器人学习笔记一
  20. mysql8有社区版吗_mysql社区版下载|Mysql Community Server下载v8.0.16 官方最新版_ IT猫扑网...

热门文章

  1. 计算机组成原理—储存器的层次结构
  2. 吉林银行2021年上半年经营成果丰硕
  3. 八字易经算法之用JAVA实现排八字神煞
  4. Python解二元一次方程,没想到如此简单
  5. oracle报错 ORA-01722: 无效数字
  6. 输入框实时字数计算移动端bug解决
  7. 知道创宇入选第九届CNCERT国家级网络安全应急服务支撑单位
  8. adb安装报错情形以及解决办法
  9. 头插法逆置单向链表c语言,单链表的逆置(头插法和就地逆置)
  10. 计算机与师范数学的联系论文,数学师范生毕业论文