从前不会回头,往后不会将就。
----小新
一.ARM采用32位架构
ARM约定一个Byte是8 bits,一个Halfword是16 bits (2 byte),一个Word是32 bits (4 byte)。大部分ARM core 提供ARM 指令集(32 bit,每条指令都是4个字节),Thumb 指令集(16bit),Thumb2指令集(16 & 32bit)。
二.ARM的7种基本工作模式
ARM处理器存在七种基本工作模式,分别是:
- 用户模式(usr):这是正常的用户模式,也是ARM处理器正常的程序执行状态。
- 快速中断模式(fiq):这种模式用于处理快速中断,对高速数据传输或通道进行处理。
- 外部中断模式(irq):这种模式用于对一般情况下的中断进行处理。
- 管理模式(svc):这种模式属于操作系统使用的保护模式,主要用于处理软件中断swi reset。
- 数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于处理存储器故障、实现虚拟存储器和存储器保护。
- 系统模式(sys):这种模式运行具有特权的操作系统任务。
- 未定义指令中止模式(und):这种模式用于处理未定义的指令陷阱,当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。
三.ARM的37个通用寄存器
(1)通用寄存器
ARM微处理器共有37个32位寄存器,其中30个为通用寄存器,1个固定用作PC,6个位状态寄存器(1个固定用作CPSR,5个固固定用作5种模式下的SPSR)。这些寄存器在ARM体系结构中有着不同的用途和功能,可以用于保存程序状态、处理数据、控制指令执行等。
(2)特殊功能寄存器
特殊功能寄存器,属于外设硬件的组成部分。使用软件编程控制某一硬件,其实就是编程读写这个硬件的特殊功能寄存器。
(1)影子式设计
上图中除了Abort模式列出所有的寄存器外,其他模式只列出对应位置该模式下特有的寄存器,没有列出的寄存器,则说明和Abort模式共用。比如User模式下有自己的r13和r14寄存器,其他寄存器和Abort模式相同。这样算下来,ARM总共有 37 个寄存器,但最多只能同时存在18个寄存器。有些寄存器虽然名字相同,但是在当前模式是不可见的。比如在ARM中有6个名叫r13的寄存器,但在特定处理器模式下,只有一个r13是当前可见的,其他的r13必须切换到对应的模式才能看到。这种设计叫影子寄存器。
这样设计的好处是,当各种异常发生的时候,每种异常模式都可以保存一些重要的数据,异常处理程序完成之后返回异常前的程序时,不会破坏原有的寄存器或状态。
(2)重要的寄存器
这37个寄存器都是32位长度,值得重点理解的寄存器有以下几个。
1.程序控制寄存器(PC,Program Control Register)
这个寄存器存放着将要执行的指令的地址,它指向哪里,CPU就会执行哪条指令,所以程序跳转时把目标代码的地址放到PC寄存器中。注意,整个CPU只有一个PC寄存器。
2.程序状态寄存器(CPSR,Current Program Status Register)
这个寄存器用来记录CPU的当前状态。注意,整个CPU只有一个CPSR寄存器。
3.程序状态保存寄存器(SPSR,Saved Program Status Register)
用来保存CPSR的,子程序返回时将SPSR赋给CPSR。注意,整个CPU有5个SPSR寄存器。
4.链接寄存器(LR,Link Register)
这个寄存器的主要作用如下:
一是调用子程序时,用来保存子程序返回地址(子程序返回时返回到哪个地址)。当通过bl或blx指令调用子程序时,硬件会自动将子程序返回地址保存在LR寄存器中。在子程序返回时,把LR的值复制到PC即可实现子程序返回。比如可以使用mov pc,lr完成子程序返回。
二是当异常发生时,LR中保存的值等于异常发生时PC的值减4,因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。
四.程序状态寄存器(CPSR)
程序状态寄存器(CPSR)是ARM处理器中的重要寄存器之一,用于存储程序状态信息。CPSR包含了条件码标志、中断禁止位、当前处理器模式标志以及其他的一些控制和状态位。在任何处理器模式下,CPSR都可以被访问。它是一个32位的寄存器,用于存储当前程序的状态信息。当特定的异常中断发生时,这个寄存器用于存放当前程序状态寄存器的内容。在异常中断退出时,可以用SPSR来恢复CPSR。由于用户模式和系统模式不是异常中断模式,所以它们没有SPSR。
CPSR中各个bit位表明了CPU的某些状态信息,这些信息非常重要,和汇编指令息息相关(比如BLE指令中的E就和CPSR中的Z标志位有关)。CPSR中的I、F位和开中断、关中断有关。CPSR中的mode位(bit4~bit0共5位)决定了CPU的工作模式,在uboot代码中会使用汇编进行设置。