• CPU模式(Mode)_状态(State)与寄存器(2)


    在上节课的介绍里,我们引入了异常的概念和处理流程,以及知道中断也是一种异常。
    本节主要学习CPU的7种Mode、2种State和相关的寄存器及异常的处理流程。

    1. ARM体系下的COU有 7 种工作模式(Mode):

              usr	    	: 用户模式 -------> ARM处理器正常的程序执行状态。
                 sys	        :系统模式 -------> 用于高速数据传输或通道处理。
              ----und(Unddefined)   :未定义指令中止模式 -------> 当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真
       这5种    |   src (Supervisor)	      	:  管理模式 -------> 操作系统使用的保护模式
       属于 ----|   abt (Abort)	    	  :数据访问中止模式 -------> 当数据或指令预取中止时进入该模式,可用于虚拟存储及存储保护。
       异常    |   irq (IRQ)	    	:中断模式 -------> 用于通用的中断处理
             ----fiq (FIQ)	    :快速中断模式 -------> 用于高速数据传输或通道处理
    

      


      1.1 abt(数据访问中止模式):(该类异常又分为两类):

        a. 指令预取中止:∵ CPU是以流水线方式来执行指令的,即执行当前指令时,同时在解析第二条指令并读取第三条指令,在读取第 3 条指令时称为预取,可能会发生错误。
        b. 比如 CPU 想要读写某个地址,可能这个过程中会出错

      1.2 除 usr 模式外,其他模式均属于特权模式。

         在这 6 种特权模式下,它们可以随遍切换到其它任何模式。在用户模式下,不能直接切换到其它模式。
         大多数程序运行于用户模式,进入特权模式是为了处理中断、异常,或者访问被保护的系统资源。

          其中注意 usr模式 为什么不能直接进入其他模式?
          用户模式在有操作系统的情况下是给应用程序去使用的,写应用程序的人水平千差万别,不能保证程序是好是坏,
          那么可以让应用程序运行于 usr模式,限制应用程序的权限,防止它破坏整个系统。

      1.3 CPSR (Current Program Status Register) 寄存器: 当前程序状态寄存器。
        CPSR 中一些位被用于标识各种状态,一些位被用于标识当前处于什么工作模式。

      1.4 为什么有那么多异常模式?
        发生某些异常时会对应进入某种异常模式,在这种异常模式下,更容易来处理这种异常(更专业☺)。

      1.5 每种异常模式下有哪些资源的差别呢?  

         实际上就是寄存器的差别。寄存器笔记在第3节。

    2. 2 种State:
      2.1 CPU 工作状态
        ARM state  :此时处理器执行 32 位的字对齐的ARM指令。
        Thumb state :此时处理器执行的 16 位的半字对齐的Thumb指令。

    1         
    2  eg:
    3                         |------ ARM     : 该指令编译成 4 Byte机器码
    4           MOV R0, R1 ---|    
    5                         |------ Thumb   : 该指令编译成 2 Byte机器码    
    6      
    7   ===> 使用Thumb指令集,就是为了减小程序使用的空间     

        韦老师的程序几乎都是在ARM状态下运行,而CPU一上电就处于ARM状态,所以无需关心CPU的工作状态。

      2.2 现在区分一下ARM指令集与Thumb指令集:
       Thumb 指令可以看作是ARM指令压缩形式的子集,是针对代码密度的问题而提出的,它具有16位的代码密度但是它不如ARM指令的效率高。
    Thumb不是一个完整的体系结构,不能指望处理器只执行Thumb指令而不支持ARM指令集。因此,Thumb指令只需要支持通用功能,必要时可以借助
    完善的ARM指令集,比如所有的异常自动进入ARM状态。在编写Thumb指令时先要使用伪指令CODE16声明,而且在ARM指令中要使用BX指令跳转
    到Thumb指令,以切换处理器状态,编写ARM指令时,则可以使用伪指令CODE32声明。

    3. 寄存器:
      3.1 通用寄存器

                      

        a. 画灰色三角形代表该寄存器是该模式下特有的寄存器,这些寄存器称为备份寄存器。
        b. 每种工作模式有 16 个寄存器 + 1 个/ 2 个 (1个或2个取决于工作模式)程序状态寄存器。
        c. 31个通用寄存器 如下:

    1  r0 -- r15 : -----> 16 个寄存器    (其中r0到r7,外加r15, 各个工作模式下都是一样的)
    2  r8_fiq -- r14_fiq    : -----> 7  个寄存器    (FIQ快中断模式独有)
    3  r13_svc-- r14_svc    : -----> 2   个寄存器    (svc管理模式独有)
    4  r13_abt-- r14_abt    : -----> 2   个寄存器    (abt数据访问中止模式独有)
    5  r13_irq-- r14_irq    : -----> 2   个寄存器    (irq中断模式独有)
    6  r13_und-- r14_und    : -----> 2   个寄存器    (und未定义指令中止模式独有)
    7       16 + 7 + 2 + 2 + 2 + 2 = 31 个通用的32位寄存器
    8         

          eg:假设执行 MOV R0, R8 ,在System&User 模式与FIQ 模式下,R0是同一个寄存器(实际上任何一种模式下,R0都是同一个寄存器),
            但在访问R8时,FIQ模式下访问的是其专有的 r8_fiq 寄存器。
              

    1             |--- sys: MOV R0, R8
    2    MOV R0, R8 ===>|
    3             |--- fiq: MOV R0, R8_fiq

        d. 5 种模式下至少会有各自的R13 和 R14专属寄存器。
        R13 称为栈指针寄存器, 通常用于保存栈指针。
        R14 称为程序链接寄存器(subroutine Link Register),当执行 BL 子程序调用指令时,R14得到R15(程序计数器PC)中的备份。
          而当发生中断或异常时,对应的R14_svc、R14_irq、R14_fiq、R14_abt、R14_und 保存R15返回值,即保存发生异常时的指令地址,以后返回时,可以返回
          R14所指示的地方。
            ||
            ||           |--- 保存现场: 保存被中断模式的寄存器,其中FIQ快中断模式有多个自己专属的寄存器,本身就不会占用其他模式的寄存器,
            /           |                       所以自然会省下保存其他模式下寄存器的时间,加快处理速度,但在Linux系统中,并不会使用FIQ模式
      这里简单复习一下中断处理流程 ---| ---  处理 :
                       | ---  恢复 :


      3.2 备份寄存器(banked register)

        进入某个工作模式后就使用对应的那组寄存器。r8_fiq -- r14_fiq、r13_svc-- r14_svc、r13_abt-- r14_abt、r13_irq-- r14_irq、r13_und-- r14_und均属于备份寄存器。

      3.3 当前程序状态寄存器(Current Program Status Register) : CPSR

                           

         CPSR中各位意义如下:

          (1) T 位: 置位时,CPU处于Thumb状态;否则处于ARM状态。

          (2) 中断禁止位:I 位和 F位属于中断禁止位。他们被置位时,IRQ中断,FIQ中断分别被禁止。

          (3) 工作模式位:表明CPU当前处于什么工作模式。可以编写这些位,使CPU进入指定的工作模式。  

          (4) 条件标志位:Z 位 

    1 eg:    
    2      CMP R0, R1  ; 如果R0 = R1 的话,Zero位置1 
    3 
    4     beq   xxx    ; 这条指令会判断一下这个寄存器里面的 Z 位,如果这一位等于1的话,它就会跳转; 若等于0的话,就不跳转。


      3.4 CPSR 的备份寄存器: SPSR(Saved Program States Register)

         SPSR(Saved Program States Register):不同模式下,有SPSR_fiq、SPSR_svc、SPSR_abt、SPSR_irq、SPSR_und 5 个不同的寄存器。

                每种模式下的SPSR寄存器用来保存被中断模式下的CPSR的值

     4. 异常的处理流程:

      4.1 异常发生时,将切换进入相应的工作模式,ARM920t的CPU核硬件自动完成如下操作:
        (1) 对于通用寄存器,在异常工作模式的连接寄存器R14(即对应的R14_svc、R14_irq、R14_fiq、R14_abt、R14_und)中保存前一个工作模式的下一条指令地址。
          对于ARM状态,对应连接寄存器保存的值 = 当前PC值 +4 或 +8(参考下表)。

            


        (2) 对于程序状态寄存器,异常模式的 SPSR = 上个模式的CPSR。
        (3) 将CPSR寄存器的工作模式位(M0--M4)设置为这个异常对应的工作模式, 进入异常模式。
        (4) 令PC值等于这个异常模式在异常向量表中的地址,即跳转去执行异常向量表中的相应指令。

    打开u-bootcpuarm920t 目录下的start.S,异常向量表如下图所示:

    1 b reset    ;复位异常 0x0    
    2 ldr    pc, _undefined_instruction      ;未定义的指令异常 0x4    遇到没有定义的指令
    3 ldr    pc, _software_interrupt       ; 软件中断异常 0x8
    4 ldr    pc, _prefetch_abort        ;内存操作异常 0xc
    5 ldr    pc, _data_abort         ; 数据异常 0x10
    6 ldr    pc, _not_used       ; 未使用 0x14
    7 ldr    pc, _irq         ; 中断IRQ异常 0x18    这里也证明中断是一种异常
    8 ldr    pc, _fiq    ; 快速中断FIQ异常 0x1c

      4.2 从异常工作模式退出回到之前的工作模式,这需要通过软件完成如下操作:
        (1) 对于通用寄存器,前面进入异常工作模式时,连接寄存器R14中保存了前一工作模式的一个指令地址 ,将它减去一个适当的值(参考上表)后赋给PC寄存器。
          即 PC = R14 - 某个值。
        (2) 对于程序状态寄存器,退回的工作模式的CPSR = 异常模式下SPSR的值。
        (3) 如果发生的是中断的话(其他异常模式不用管这一步),清除中断

  • 相关阅读:
    应用实例:用户登录(2009.10.23)
    ASP.NET学习笔记:服务器控件 (2009.11.9)
    小实例:模拟电话簿
    用Iframe实现左边TreeView导航,右边显示相应内容的布局
    HTML&CSS&JaveScript学习笔记(2009.11.19)
    C#中问号(?)的用法
    GridView的简单分页等
    GridView正反双向排序
    代码理解(2009.11.20)
    ASP.NET学习笔记:数据库操作 (2009.11.10)
  • 原文地址:https://www.cnblogs.com/JmZd/p/8809997.html
Copyright © 2020-2023  润新知