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-boot\cpu\arm920t 目录下的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) 如果发生的是中断的话(其他异常模式不用管这一步),清除中断

 

posted @ 2018-04-12 19:38  家门Jm  阅读(2499)  评论(0编辑  收藏  举报