Work With ARM - 浅析ARM的寄存器(1)

Work With ARM - 浅析ARM的寄存器(1)

RISC的目的是将指令简单化和规范化(这并不表示RSIC CPU的指令就少),为了实现这一目标, RISC:
   (1) 规定所有的指令都是固定长度(一般为4个字节,ARM的THUMB模式下为2个字节),这可以使CPU指令预取模块简单化,并使得流水线设计更加简单。
   (2) 所有的运算类操作在寄存器之间进行,很明显可以减少芯片的复杂度,降低成本,并使得指令的执行时间是可以预测的,方便了开发人员。
   (3) 提供专门的内存访问指令在寄存器和内存之间交换数据,这可以减小芯片的复杂度,同时可以优化内存存取,这对流水线影响也是很大的,可以优化流水线的设计。

    RISC这样做的目的是为了降低芯片设计的复杂度,减少芯片体积。这样设计的一个基本依据是“在一个指令系统中,只有20%的指令是常用的”,因此如果将所有指令等同对待去做设计,本身就是一种不公平的设计。正确的做法是对那些20%的常用指令进行优化设计,并优先考虑,而对那些很少用到的80%指令,一般通过那些常用指令的组合来获得,或者将这些工作留给软件开发人员。
    由于RISC的所有操作都在寄存器之间进行,因此所有RISC结构的计算机的显著特点是包含大量的寄存器,比如ARM就有30个以上寄存器:
    (1) 通用寄存器R0 ~ R15
    (2) 状态仅存器CPSR及其不同模式下的影子寄存器
    (3) 不同模式下的影子寄存器

影子寄存器

    影子寄存器的引入是ARM的一个特点(就我目前的知识,X86,MIPS和PowerPC好像都没有)。我们知道,ARM有16个通用寄存器,这16个通用寄存器在指令中使用4个bit来标识,但是在不同的模式下,同样的4个bit 指向不同的物理寄存器,这些不同的物理寄存器就被称之为影子寄存器。不同的通用寄存器的影子寄存器个数也不相同,有的没有,有的只有1个,有的多达5个。要记住一点:所有的影子寄存器都是一个实际存在的物理寄存器。
    ARM CORE是一个非常紧凑的设计,影子寄存器的引入就是这种设计的表现。通过引入影子寄存器,指令可以重复使用相同的寄存器编码,但是在不同模式下,这些编码对应不同的物理寄存器。比如Abort模式下的R13就同用户模式下的R13不同,虽然它们编码一样,但是实际上对应的是不同的物理寄存器(可以将CPSR的模式域当作片选)。
    我们可以计算一下ARM的通用寄存器数目
    (1) 1个状态寄存器
    (2) 5个异常模式下的状态寄存器的影子寄存器
    (3)16个通用寄存器R0 ~ R15
    (4)10个异常模式下的R13和R14的影子寄存器
    (5) 5个FIQ模式下的R8 ~ R12的影子寄存器

    总共是1 + 5 + 16 + 10 + 5 = 37个寄存器,这个数目同X86相比要多很多。

    由于影子寄存器的编码同其所Banked的寄存器的编码是一样的,因此象“MOV R0, R13”这样的指令,在不同的模式下,访问的是不同的物理寄存器R13,这意味我们在异常模式下是不能访问正常意义上的R13的,这对一般的寄存器可能关系不大。
    但是,对状态寄存器CPSR而言,这是很恼人的,因为要切换CPU的状态,只能通过修改状态寄存器CPSR来进行,对CPSR的影子寄存器的修改并不能影响CPSR本身,这也就是为什么会有MOV和MOVS,SUB和SUBS的原因。但是,象TEQ,BEQ等这样的比较指令修改的是CPSR的内容,而不是该模式下CPSR影子寄存器的内容。这也是CPSR同一般Rx不一样的地方:CPSR对所有异常模式都是可见的,只不过这种可见性并不表示指令可以直接读取或修改CPSR的内容,更准确的说,这种可见性是对指令系统(如TEQ, BEQ等条件判断指令)而言的,只能通过特殊的指令来影响CPSR中的相关域,而不能直接读取或修改CPSR,因此CPSR对程序员的是不可见的。

    引入影子寄存器的另外一个目的是当中断或异常产生时,CPU会将当前“CPU的状态”保存在影子寄存器中。从CPU角度看,它的“状态”包括:
    (1)  PC(也就是R15)值
    (2)  CPSR的值

    您也许认为R0等通用寄存器也是状态,从某种意义上说您是对的。但是那些不是“CPU的状态”,它们是“应用的状态”。当中断或异常产生后,CPU并不“Care”它们,CPU只是:
    (1) PC值被保存在当前模式下的R14中
    (2) CPSR值被保存在当前模式下的影子寄存器中
     保存CPU的状态是一种廉价的操作,但是要保存应用的状态可就很昂贵了,因为至少有13个寄存器(R0 ~ R12)需要保存,为了加快这种操作,ARM的内存访问指令可以将一组寄存器的内容保存到内存中,反之亦然。

你可能感兴趣的:(with,work,-,ARM,浅析ARM的寄存器(1))