CPU模式(Mode)、状态(State)与寄存器

文章目录

    • 1 CPU模式(Mode)、状态(State)与寄存器概述
    • 2 CPU的两种状态
    • 3 CPU模式及状态寄存器
      • 3.1 CPU模式简介
      • 3.2 各个模式下的寄存器
      • 3.3 CPSR和SPSR寄存器
      • 3.4 异常发生时CPU是如何协同工作的

1 CPU模式(Mode)、状态(State)与寄存器概述

7种Mode:

  • usr/sys
  • undefined(und)
  • Supervisor(svc)
  • Abort(abt)
  • IRQ(irq)
  • FIQ(fiq)

2种State:

  • ARM state
  • Thumb state

寄存器:

  • 通用寄存器
  • 备份寄存器(banked register)
  • 当前程序状态寄存器(Current Program Status Register):CPSR
  • CPSR的备份寄存器:SPSR(Save Program Status Register)

2 CPU的两种状态

CPU有两种state:

  • ARM state:使用ARM指令集,每个指令4byte。
  • Thumb state:使用的是Thumb指令集,每个指令2byte。

比如同样是:mov R0, R1 编译后,对于ARM指令集要占据4个字节机器码;对于Thumb指令集占据2个字节机器码。引入Thumb减少存储空间。

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


3 CPU模式及状态寄存器

3.1 CPU模式简介

我们仍然以这个母亲为例讲解这个CPU模式 :
这个母亲无压力看书(正常模式) -->要考试,看书(兴奋模式) —>生病(异常模式)。

对于ARM CPU有7种模式:

  • usr:类比 正常模式
  • sys:类比的话兴奋模式
  • 5种异常模式:(2440用户手册72页)
    • und :未定义模式
    • svc :管理模式
    • abt :终止模式
      • 指令预取终止(读写某条错误的指令导致终止运行)
      • 数据访问终止 (读写某个地址,这个过程出错),都会进入终止模式
    • IRQ: 中断模式
    • FIQ: 快中断模式

我们可以称以下6种为特权模式:

  • und :未定义模式
  • svc :管理模式
  • abt :终止模式
  • IRQ :中断模式
  • FIQ :快中断模式
  • sys :系统模式

usr用户模式(不可直接进入其他模式),特权模式可以编程操作CPSR直接进入其他模式 。

3.2 各个模式下的寄存器

CPU模式(Mode)、状态(State)与寄存器_第1张图片

可以看到在每种模式下都有R0 ~ R15,在这张图注意到有些寄存器画有灰色的三角形,表示访问该模式下访问的专属寄存器比如:

mov R0, R8
mov R0, R8

在System 模式下访问的是R0和R8,在所有模式下访问R0都是同一个寄存器。但是在FIQ模式下,访问R8是访问的FIQ模式专属的R8寄存器,不是同一个物理上的寄存器。

在这五种异常模式中每个模式都有自己专属的R13 R14寄存器,R13用作SP(栈) 、R14用作LR(返回地址) 。LR是用来保存发生异常时的指令地址。

为什么快中断(FIQ)有那么多专属寄存器?这些寄存器称为备份寄存器

回顾一下中断的处理过程:

  1. 保存现场(保存被中断模式的寄存器)。
    就比如说我们的程序正在系统模式/用户模式下运行,当你发生中断时,需要把R0 ~ R14这些寄存器全部保存下来,然后处理异常,最后恢复这些寄存器。但如果是快中断,那么我就不需要保存 系统/用户模式下的R8 ~ R12这几个寄存器,在FIQ模式下有自己专属的R8 ~ R12寄存器,省略保存寄存器的时间,加快处理速度,但是在Linux中并不会使用FIQ模式。

  2. 处理。

  3. 恢复现场。

3.3 CPSR和SPSR寄存器

CRSR当前程序状态寄存器,这是一个特别重要的寄存器,SPSR保存程序状态寄存器,他们格式如下:
CPU模式(Mode)、状态(State)与寄存器_第2张图片

首先 M4 ~ M0 表示当前CPU处于哪一种模式(Mode);我们可以读取这5位来判断CPU处于哪一种模式,也可以修改这一种模式位,让其修改这种模式;假如你当前处于用户模式下,是没有权限修改这些位的;

M4 ~ M0对应什么值,会有说明:
CPU模式(Mode)、状态(State)与寄存器_第3张图片

其他位:

  • Bit5 State bits表示CPU工作与Thumb State还是ARM State用的指令集是什么。
  • Bit6 FIQ disable当bit6等于1时,FIQ是不工作的。
  • Bit7 IRQ disable当bit5等于1时,禁止所有的IRQ中断,这个位是IRQ的总开关。
  • Bit8 ~ Bit27是保留位。
  • Bite28 ~ Bit31是状态位。

状态位:
什么是状态位,比如说执行一条指令:cmp R0, R1。
如果R0 等于 R1 那么zero位等于1,这条指令影响 Z 位,如果R0 == R1,则Z = 1。beq跳转到xxx这条指令会判断Bit30是否为1,是1的话则跳转,不是1的话则不会跳转。使用 Z 位,如果 Z 位等于1 则跳转,这些指令是借助状态位实现的。

SPSR保存的程序状态寄存器: 表示发生异常时这个寄存器会用来保存被中断的模式下的CPSR。就比如我的程序在系统模式下运行 CPSR是某个值,当发生中断时会进入irq模式,这个CPSR_irq就保存系统模式下的CPSR。

3.4 异常发生时CPU是如何协同工作的

进入异常的处理流程(硬件) :
CPU模式(Mode)、状态(State)与寄存器_第4张图片
我们来翻译一下,发生异常时,我们的CPU会做什么事情?

  1. 把下一条指令的地址保存在LR寄存器里(某种异常模式的LR等于被中断的下一条指令的地址),它有可能是PC + 4有可能是PC + 8,到底是那种取决于不同的情况。
  2. 把CPSR保存在SPSR里面(某一种异常模式下SPSR里面的值等于CPSR)。
  3. 修改CPSR的模式为进入异常模式(修改CPSR的M4 ~ M0进入异常模式)。
  4. 跳到向量表。

退出异常的处理(软件):
CPU模式(Mode)、状态(State)与寄存器_第5张图片

  1. 让LR减去某个值,让后赋值给PC(PC = 某个异常LR寄存器减去 offset)。减去什么值呢?也就是我们怎么返回去继续执行原来的程序,根据下面这个表来取值。
    CPU模式(Mode)、状态(State)与寄存器_第6张图片
    如果发生的是SWI可以把 R14_svc复制给PC,如果发生的是IRQ可以把R14_irq的值减去4赋值给PC。

  2. 把CPSR的值恢复(CPSR 值等于 某一个一场模式下的SPSR)。

  3. 清中断(如果是中断的话,对于其他异常不用设置)

你可能感兴趣的:(Linux)