layout: post
title: “基础(寄存器-栈-中断向量表)”
date: 2024-1-16 15:39:08 +0800
tags: Cotex-M3
R0 -R7也被称为低组寄存器。所有指令都能访问它们。它们的字长全是32位,复位后的初始值是不可预料的
R8 -R12也被称为高组寄存器。这是因为只有很少的16位Thumb指令能访问它们,32位的thumb-2指令则不受限制。它们也是32位字长,且复位后的初始值是不可预料的。
当引用R13(或写作SP)时,引用到的是当前正在使用的那一个,另一个必须用特殊的指令来访问(MRS,MSR指令)
R14是连接寄存器(LR)。在一个汇编程序中,你可以把它写作both LR和R14。LR用于在调用子程序时存储返回地址。例如,当你在使用BL(分支并连接,Branch and Link)指令时,就自动填充LR的值。
LR的LSB却是可读可写的。这是历史遗留的产物。在以前,由位0来指示ARM/Thumb状态。因为其它有些ARM处理器支持ARM和Thumb状态并存,为了方便汇编程序移植,CM3需要允许LSB可读可写
R15是程序计数器,在汇编代码中一般我们都都叫它的外号“PC”。 因为CM3内部使用了指令流水线,读PC时返回的值是当前指令的地址+4
CM3中的指令至少是半字对齐的,所以PC的LSB总是读回0。然而,在分支时,无论是直接写PC的值还是使用分支指令,都必须保证加载到PC的数值是奇数(即LSB=1),用以表明这是在Thumb状态下执行。倘若写了0,则视为企图转入ARM模式,CM3将产生一个fault异常
它们只能被专用的MSR/MRS指令访问,而且它们也没有与之相关联的访问地址
MRE , ; 读取寄存器到通用寄存器
MSR , ;写通用寄存器的值到特殊功能寄存器
- PSR位的类型:
预留位:为将来的扩展预留
用户可写位:在任意模式下都可写,N,Z,C,V,Q,和GE[3:0]以及E位都是用户可写的。
特权模式位:在特权模式下可写,用户模式下写特权位没有效果,A,I,F,T和M[4:0]都是特权位。
执行状态位:在特权模式下可写,用户模式下写执行状态位没有效果,J和T位都是执行状态位,在ARM状态下一直为0
- 应用程序: PSR(APSR)
- N: 负数 ? 1 : 0 - Z: 运算结果为0 ? 1 : 0 - C: 进位标志.(4中情况) 1. 加法指令(包括CMN): 当结果产生了进位,则为1,表示无符号数运算发生溢出; 2. 减法指令(包括CMP): 当运算中发生了错位,为1, 表示运算发生下溢出; 3. 对已在操作数中包含移位操作的运算指令,C被置为被移位寄存器最后移出去的位; 4. 对于其他非加/减的运算指令,c一般不收影响; - V: 溢出标志位: 对于加减法,当操作数和运算结果都是以二进制的补码表示的带符号的数,切运算结果超出了有符号运算的范围溢出,V=1.
- 中断号: PSR(IPSR)
- 执行: PSR(EPSR)
通过MRS/MSR指令,这3个PSRs即可以单独访问,也可以组合访问(2个组合,3个组合都可以)。当使用三合一的方式访问时,应使用名字“xPSR”或者“PSR”。
要访问PRIMASK, FAULTMASK以及BASEPRI,同样要使用MRS/MSR指令
在Cortex-M3的handler模式中,CONTROL[1]总是0。在线程模式中则可以为0或1。因此,仅当处于特权级的线程模式下,此位才可写,其它场合下禁止写此位。改变处理器的模式也有其它的方式:在异常返回时,通过修改LR的位2,也能实现模式切换。这是LR在异常返回时的特殊用法,颠覆了对LR的传统使用方式
FreeRTOS里面使用到了
仅当在特权级下操作时才允许写该位。一旦进入了用户级,唯一返回特权级的途径,就是触发一个(软)中断,再由服务例程改写该位
在线程模式+用户级下,对系统控制空间(SCS)的访问将被阻止——该空间包含了配置寄存器组以及调试组件的寄存器组。除此之外,还禁止使用MRS/MSR访问刚才讲到的,除了APSR之外的特殊功能寄存器。如果以身试法,则对于访问特殊功能寄存器的,访问操作被忽略;而对于访问SCS空间的,将fault伺候。
NVIC还有一条NMI输入信号线。NMI究竟被拿去做什么,还要视处理器的设计而定。在多数情况下,NMI会被连接到一个看门狗定时器,有时也会是电压监视功能块,以便在电压掉至危险级别后警告处理器。NMI可以在任何时间被激活,甚至是在处理器刚刚复位之后
STM32连接的是CSSI中断, 当外部时钟异常的时候触发中断
支持一次多个寄存器
PUSH {R0-R2} ;压入R0-R2
PUSH {R3-R5,R8, R12} ;压入R3-R5,R8,以及R12
POP {R3-R5,R8, R12} ;弹出R3-R5,R8,以及R12
POP {R0-R2} ;弹出R0-R2
在使用的时候汇编器会把寄存器进行升序排列
PUSH {R0-R3, LR}
POP {R0-R3, PC}
在使用OS的环境下,只要OS内核仅在handler模式下执行,用户应用程序仅在用户模式下执行,这种双堆栈机制派上了用场——防止用户程序的堆栈错误破坏OS使用的堆栈。
在特权级的时候使用MRS和MSR进行设置两个堆栈指针
从0地址的位置获取到复位函数和栈指针的值
因为CM3使用的是向下生长的满栈,所以MSP的初始值必须是堆栈内存的末地址加1
由于存储的是PC的值, 又是在Thumb模式下面进行的, 所以地址最低位设置为1