8.1.ARM编程模式和工作模式
(1)ARM的基本设定:ARM约定Byte(8bits)、Halfworld(16bits,2byte)、World(32bits,4byte)。大部分ARM的CPU提供指令集:Thumb指令集(16bit,所有的指令集是16位的,优点是能节省内存;缺点是指令集不健全,譬如异常处理需要两条16位的指令去完成某件事,编程复杂需要来回切换ARM状态和Thumb状态)、ARM指令集(32bit,所有的指令集是32位的,好处是编程简单;缺点是浪费内存)、Thumb2指令集(16&32bit,指令集有16位和32位的,ARMv7的时候推出,S5PV210使用的是该指令集,等于ARM指令集和Thumb指令集的集合)。Jazelle cores支持Java bytecode,用于提供Java加速。
(2)ARM处理器工作模式:User(非特权模式,大部分任务执行在这种模式);System(使用和User模式相同寄存器集的特权模式);FIQ(当一个高优先级(fast) 中断产生时将会进入这种模式);IRQ(当一个低优先级(normal) 中断产生时将会进入这种模式);Supervisor(当复位或软中断指令执行时将会进入这种模式);Abort(当存取异常时将会进入这种模式); Undef(当执行未定义指令时会进入这种模式)。
(3)注意:除User(用户模式)是Normal(普通模式)外,其他6种都是Privilege(特权模式)。Privilege中除Sys模式外,其余5种为异常模式。各种模式的切换,可以是程序员通过代码主动切换(通过写CPSR寄存器);也可以是CPU在某些情况下自动切换。各种模式下的权限和可以访问的寄存器不同。
(4)CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件需要,便于实现软件特性。操作系统有安全级别要求,因此CPU设计多种模式是为了方便操作系统的多种角色安全等级需要。
8.2.ARM的37个寄存器详解
(1)ARM总共有37个寄存器,但是每种模式下最多只能看到18个寄存器,其它寄存器虽然名字相同但是在当前模式不可见。譬如对r13这个名字来说,在ARM*有6个名叫r13(又叫sp)的寄存器,但是在每种特定处理器模式下,只有一个r13是当前可见的,其它的r13必须切换到它的对应模式下才能看到,该种设计叫影子寄存器(banked register),影子寄存器设计的优点是当各种异常发生的时候,每种异常模式都可以保存一些重要的数据,使异常处理程序完成之后返回异常前的程序时不会破坏原有的寄存器或状态。
(2)ARM共有37个寄存器,都是32位长度;37个寄存器中30个为”通用”型,1个固定用作PC,1个固定用作CPSR,5个固定用作5种异常模式下的SPSR(见图1)。
(3)CPSR寄存器:CPSR中各个bit位表明了CPU的某些状态信息,这些信息非常重要,和后面学到的汇编指令息息相关(譬如BLE指令中的E就和CPSR中的Z标志位有关);CPSR中的I、F位和开中断、关中断有关;CPSR中的mode位(bit4~bit0共5位)决定了CPU的工作模式,在uboot代码中会使用汇编进行设置(见图2)。
(4)PC(r15)程序控制寄存器:PC(Program control register)为程序指针,PC指向哪里,CPU就会执行哪条指令(所以程序跳转时就是把目标地址代码放到PC中);整个CPU中只有1个PC(CPSR也只有1个,但SPSR有5个)。
8.3.ARM的异常处理方式
(1)异常:正常工作之外的流程都叫异常,异常会打断正在执行的工作,并且一般我们希望异常处理完成后继续回来执行原来的工作(保存现场),中断是异常的一种。
(2)异常向量表:所有的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的;当异常发生时,CPU会自动动作(PC跳转到异常向量处处理异常,有时伴有一些辅助动作);异常向量表是硬件向软件提供的处理异常的支持(见图3)。
(3)ARM异常处理机制:异常处理中有一些是硬件自动做的,有一些是程序员需要自己做的。需要搞清楚哪些是需要自己做的,才知道如何写代码。CPU设计时提供的异常向量表一般为一级向量表,有些CPU为了支持多个中断,还会提供二级中断向量表,处理思路类似于这里说的一级中断向量表(见图3)。