ARM微处理器的37个物理寄存器被安排成部分重叠的组,它们不是在任何模式下都可以使用的,寄存器的使用与处理器状态和工作模式有关。如图2-4所示,每种处理器模式使用不同的寄存器组。其中15个通用寄存器(R0~R14)、1或2个状态寄存器和程序计数器是通用的。图2-4中有背景阴影的寄存器均为独立的物理寄存器,R0~R14、PC、CPSR这17个寄存器也是独立的物理寄存器,共有37个物理寄存器。
图2-4 寄存器组织结构图
通用寄存器(R0~R15)可分成未分组寄存器R0~R7、分组寄存器R8~R14和程序计数器R15三类。
在所有的运行模式下,未分组寄存器都指向同一物理寄存器,它们没有被系统指定特殊的用途。因此,在中断或异常处理进行运行模式转换时,由于不同的微处理器运行模式均使用相同的物理寄存器,可能会造成寄存器中数据的破坏,这点在程序设计时要引起注意。未分组寄存器R0~R7是真正的通用寄存器,可以工作在所有的处理器模式下,没有隐含的特殊用途。
对于分组寄存器,它们每一次所访问的物理寄存器与微处理器当前的运行模式相关。分组寄存器R8~R14的使用取决于当前的处理器模式,每种模式有专用的分组寄存器以加快异常处理的速度。
寄存器R8~R12可分为两组物理寄存器。一组用于FIQ模式,另一组用于除FIQ以外的其他模式。第一组是R8_fiq~R12_fiq,在进行快速中断处理时使用。第二组是在除FIQ模式以外的其他处理器运行模式中直接使用R8~R12,需要注意在运行模式切换时寄存器中内容的使用。寄存器R8~R12没有任何指定的特殊用途。
寄存器R13~R14可分为6个分组的物理寄存器。一组用于用户模式和系统模式,而其他5组分别用于svc、abt、und、irq和fiq五种异常模式。访问时需要指定它们的模式,如R13_<mode>,R14_<mode>;其中<mode>可以是svc、abt、und、irq和fiq模式中的一个。
寄存器R13通常用作堆栈指针,称作SP。每种异常模式都有自己独立的物理寄存器R13,在Bootloader中或在ARM应用系统的初始化过程中,一般都要初始化每种模式下的R13,即堆栈指针,使其指向该运行模式下的内存堆栈空间。在异常处理程序的入口处,将用到的其他寄存器的值保存到该指针所指向的内存堆栈中;返回时,重新将这些值加载到寄存器。这种异常处理方法保证了异常出现后不会导致执行程序的状态不可靠。
寄存器R14用作子程序链接寄存器,也称为链接寄存器(Link Register,LR),在上述的6个分组中都具有独立的物理寄存器,用于保存在发生异常时当前程序的PC指针值,使微处理器在执行完异常处理程序时能够返回到原程序。当执行带链接分支(BL)指令时,得到R15的备份。
当中断或异常出现时,或者当中断或异常程序执行BL指令时,相应的分组寄存器R14_svc、R14_irq、R14_fiq、R14_abt和R14_und用来保存R15的返回值。在其他情况下,R14也可以作为通用寄存器使用。
FIQ模式有7个分组的寄存器R8~R14,映射为R8_fiq~R14_fiq,它们是独立的物理寄存器。在ARM状态下,FIQ异常处理程序没有必要保存其他运行模式下的R8~R14寄存器,达到了快速中断的要求。其他运行模式中都包含两个分组的寄存器R13和R14的映射,它们也是独立的物理寄存器,允许每种模式都有自己的堆栈和链接寄存器。
寄存器R15用作程序计数器(PC)。在ARM状态,位[1:0]为0,位[31:2]保存PC值。在Thumb状态,位[0]为0,位[31:1]保存PC值。R15虽然也可用作通用寄存器,但一般不这样用,因为对R15的使用有一些特殊限制,当违反了这些限制时,程序执行结果是不可预知的。
由于ARM体系结构采用了多级流水线技术,对于ARM指令而言,PC总是指向当前执行指令的下两条指令的地址,即PC的值是当前指令的值+8(字节)。
● 读程序计数器。指令读出的R15值是指令地址加上8字节。由于ARM指令始终是字对齐的,所以读出结果值的位[1:0]总是0。读PC主要用于快速地对邻近的指令和数据进行位置无关寻址,包括程序中的位置无关转移。
● 写程序计数器。写R15的通常结果是将写到R15中的值作为指令地址,并以此地址发生转移。由于ARM指令要求字对齐,通常希望写到R15中值的位[1:0]=0b00。
程序状态寄存器有两类,一类是当前程序状态寄存器(Current Program Status Register,CPSR),通常也可以叫作R16寄存器,它是所有运行模式下的公用寄存器,用于保存当前运行模式下的状态字,在所有处理器运行模式下都可以使用;还有一类叫作程序状态保存寄存器(Saved Program Status Register,SPSR),从图2-4中可以看出SPSR几乎在每种运行模式下都以独立的物理寄存器而存在,它在异常发生转换时保存CPSR的值,以保证在异常返回时程序的状态字不变,它与CPSR有相同的内容格式,它们的字结构组织格式如图2-5所示。模式位控制字及其使用的寄存器见表2-1。
图2-5 程序状态寄存器格式图
表2-1 模式位控制字与运行模式及使用的寄存器
CPSR包含条件标志位(N、Z、C、V)、中断禁止位(I、F)、当前处理器模式位(T)以及其他状态和控制信息位(M4~M0)。具体代表的物理意义如下。
N、Z、C、V(Negative、Zero、Carry、oVerflow)均为条件码标志位(Condition Code Flags),它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。
CPSR中的条件标志位是由ARM指令进行清0和置1的,大部分的汇编指令只有带上对条件标志位有影响的字符“S”时才能起作用,少数的比较指令(CMN、CMP、TEQ、TST)不带影响字符“S”也可对条件标志位起作用。
在ARM状态下,绝大多数指令的执行,CPSR条件标志位是决定因素之一,另一个因素就是在汇编指令中必须带上执行的条件标识字符。ARM为了提高汇编指令的执行效率,指令的执行是有条件的。
条件标志位的通常含义如下。
1)负号标志位N:如果结果是带符号的二进制补码,那么,若结果为负数,则N=1;若结果为正数或0,则N=0。
2)零标志位Z:若指令的执行结果为0,则置1(通常表示比较的结果为“相等”),否则清0。
3)进位标志位C:可用如下4种方法之一进行设置。
● 执行加法指令(包括比较指令CMN)时,若加法产生进位(即无符号溢出),则C置1;否则置0。
● 执行减法指令(包括比较指令CMP)时,若减法产生借位(即无符号溢出),则C置0;否则置1。
● 对于结合移位操作的非加法/减法指令,C值为移出值的最后1位。
● 对于其他非加法/减法指令,C通常不改变。
4)溢出标志位V:可用如下两种方法设置。
● 对于加法或减法指令,如果操作数和结果都是补码形式的带符号整数,当发生带符号溢出时,V置1。
● 对于非加法/减法指令,V通常不改变。
程序状态寄存器CPSR的最低8位I、F、T和M[4:0]用作控制位。当异常出现时,改变控制位。处理器在特权模式下也可由软件改变。
1)普通中断控制位I:置1禁止IRQ普通中断;清0允许IRQ普通中断。
2)快速中断控制位F:置1禁止FIQ快速中断;清0允许FIQ快速中断。
T=0:指示工作在ARM状态;T=1:指示工作在Thumb状态。
M4、M3、M2、M1和M0(M[4:0])是模式控制位,也是状态信息位。它的取值组合决定处理器的运行模式,表2-1列出了模式位控制字以及该模式下可以使用的寄存器。并非所有的模式位组合都能定义一种有效的处理器模式。其他组合的结果不可预知。
程序状态寄存器的其他位目前保留,用作以后功能的扩展。
有关Thumb寄存器的组织结构请参考相关书籍,这里不再赘述。