首先对应ARM架构,如果处理的是存储器中的数据,就需要将数据从存储器加载到寄存器中。

        在M3和M4处理器中,共有16个寄存器,其中13个是通用用途的寄存器,3个为特殊用途的寄存器

通用目的寄存器:R0-R12

        这13个寄存器为通用的寄存器,前面八个R0-R7为低位寄存器,许多16位指令只能访问低寄存器,R8-R12为高寄存器,可以用于32位指令和少部分16位指令。不论是低寄存器还是高寄存器,它们的初始值都是未定义的

栈指针:R13或者叫SP

        该寄存器可以通过PUSH和POP操作实现栈存储的访问(压栈和出栈),如上图所示,存在两个栈指针,MSP(主栈指针)和PSP(进程栈指针),其中MSP为默认指针,在复位后或者处理器处于处理模式的时候使用;PSP则只能用于线程模式。栈指针的选择由特殊寄存器CONTRO决定。

链接寄存器:R14也叫LR

        该寄存器用于函数或者子程序调用时返回地址的保存。在函数或者子函数结束时,程序控制可以通过将LR的数值加载到程序计数器PC中返回调用程序处并继续执行。在执行函数调用后,LR的值会自动更新。若某函数需要调用另外一个函数,则它需要将LR的数值保存到栈中,否则,当执行了函数调用后LR的当前值会丢失。

        在异常处理期间,LR会被自动更新为特殊的EXC_RETURN数值,之后该数值会在异常处理结束的时候触发异常返回(可以根据这个特点很有效的解决硬件错误的问题)

程序计数器:R15或者PC

        该寄存器是可读可写的,读操作返回当前指令地址+4。写操作会引起跳转操作。PC存储的是当前指令的下一条指令。

        多数情况下,跳转和调用由专门的指令实现,利用数据处理指令更新PC的情况很少,但是在访问位于程序存储器中的字符数据时,PC数值非常有用,存储器读操作经常将PC作为基地址寄存器,而地址偏移由指令中的立即数生成。

特殊寄存器

        除了上述那16个寄存器外,处理器中还存在多个特殊寄存器,这些寄存器表示处理器的状态、定义了操作状态和中断/异常屏蔽。在开发嵌入式系统或需要高级中断屏蔽特性时就要访问他们。

        特殊寄存器未经过存储器映射时,可以使用MSR和MRS等访问指令进行访问。

               

(1)程序状态寄存器

        主要包括这三个状态寄存器:

                a.应用PSR(APSR)

                b.执行PSR(EPSR)

                c.中断PSR(IPSR)

(2)PRIMASK、FAULTMASK、BASEPRI寄存器

        这三个寄存器都用于异常或者中断屏蔽,每个异常都具有一个优先等级,数值越小的优先级高,反之亦然。这些寄存器可以基于优先等级屏蔽异常,但是只有在特权访问等级才可以对它们进行操作(非特权状态下写操作会被忽略,读出为0)。它们默认为0,也就是屏蔽异常中断不起作用。

        如图所示,PRIMASK寄存器为1位宽的中断屏蔽器,在为1时,会阻止不可屏蔽中断(NMI)和HardFault异常之外的所有异常(包括中断)。实际上是将当前异常优先级提升到0,这也是可编程异常/中断的最高优先级。常应用于对时间要求很严格的进程中禁止所有中断,进程结束之后复位重新使能。

        FLAUTMASK寄存器与PRIMASK类似,但是FLAUMASK可以屏蔽HardFault异常,也就是将优先等级提升到-1。FLAUMASK在异常返回时会自动清除。

        BASEPRI寄存器会根据优先级等级屏蔽异常和中断。为0时不起作用,非0时,会屏蔽具有相同或者更低优先级的异常(中断),更高优先级还可以被处理器接受。

        CMSIS-CORE提供多种方式访问这些寄存器,但是想要访问这些寄存器需要再特权级等级下访问。

x =_ get_BASEPRI();//读BASEPRI寄存器

x =_ get_ _PRIMARK();//读PRIMASK寄存器

x =_ _get_FAULTMASK();//读FAULTMASK寄存器

_set_ _BASEPRI(x);//设置BASEPRI的新数值

_set_ PRIMASK(x);//设置PRIMASK的新数值

_set_ FAULMASK(x);//设置FAULTMASK的新数值

_disable_ irq();//设置PRIMASK,禁止IRQ

_enable_ irq();//清除PRIMASK,使能IRQ

       

                

     (3)CONTROL寄存器

                该寄存器定义了:

                a.栈指针的选择(MSP,PSP)

                b.线程模式的访问等级(特权/非特权)

                在M4内核中,CONTROL寄存器有一位表示当前正在执行的代码是否使用浮点单元。

                CONTROL寄存器只能在特权访问等级进行修改操作,读取操作无限制。CONTROL寄存器的位域如图所示;

        ​​​​​​​              ​​​​​​​        

复位后,CONTROL寄存器默认为0,这也就意味着处理器此时处于线程模式、具有特权访问权限以及使用主栈指针。通过写CONTROL寄存器,特权线程模式的程序可以切换栈指针的选择或进人非特权访问等级,如下图所示。不过,nPRIV(CONTROL的第0位)置位后,运行在线程模式的程序就不能访问CONTROL寄存器了。

        ​​​​​​​        

        运行在非特权等级的程序无法再切换回特权访问等级,这样就提供了一个基本的安全模 型。例如,嵌人式系统中可能会具有运行在非特权访问等级的不受信任的应用,这些应用的访 问权限就需要受到限制,以免不可靠的程序引起整个系统的崩溃。         若有必要将处理器在线程模式切换回特权访问等级,则需要使用异常机制。在异常处理期间,处理程序可以清除nPRIV位,如图所示。在返回到线程模式后,处理器就会进入特权访问等级。

在C中的使用

使用方式

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: