对于状态寄存器的修改要遵守以下原则:
l 不修改和使用状态寄存器中未定义的位:这些在当前ARM版本中未使用的状态位,在之后的版本中可能会被用作新的用途。如果我们使用了这些位,在新的处理器中程序可能会无法正确运行。所以我们不应该使用状态寄存器中为未定义的位,应该保证这些位不被改变。
l 通常要遵循读取->修改->写会的原则:这个原则保证了我们在修改状态寄存器的某些位是保证其它位不受影响。
如图3.3所示,ARM微处理器中按8位一组,将状态寄存器(CPSR/SPSR)分为4个可分别写的区。各个区的含义如下:
l 控制(c)BIT[0-7]:CPSR的低8位(I、F、T及M[4∶0])统称为控制位。当异常发生时,这些位的值将由硬件自动改变。另外,当在特权模式时,可以通过软件编程来修改这些位的值。
l 扩展(x)BIT[8-15]:保留为将来使用。
l 状态(s)BIT[16-23]:保留为将来使用。
l 标识(f)BIT[24-31]:数据处理指令的运算结果会对CPSR的条件标志位产生影响,如:比较和测试指令(CMN、CMP、TEQ、TST);在算术、逻辑运算和数据传输指令中,目的寄存器不是R15时,可以通过在这些指令末尾加标志“S”来通知处理器指令的执行结果影响标志位。
分为4个可以独立写的区是为了提高修改状态寄存器的效率。前面我们指出对状态寄存器(CPSR/SPSR)的修改应该遵循读取->修改->写回的方法,但这样需要至少3条指令,效率相对较低;分成4个可以独立写的区(即修改其中的一个区而不影响其他24位的值),这样当我们知道某个区是确定的值的时候,修改状态寄存器就可以用一条指令直接修改状态寄存器的这个区,而不必再采用读取->修改->写回的方法了,因此可以提高修改状态寄存器的效率。具体见MSR指令说明。
下面给出几个影响和修改状态寄存器的例子。
(1)当CPSR中Z=0,R1=1时,执行指令:SUBS R1,R1,#1,指令执行完后R1=0,
CPSR中Z=1。SUB因为指定了“S”标志,所以SUB指令根据运算的结果影响了CPSR的Z位。
(2)数据处理指令的目标寄存器是R15时,如果指定“S”标志,则硬件自动将SPSR寄存器的值复制到CPSR寄存器中,在异常返回时可以使用这种方法。
(3)直接使用MSR指令向CPSR/SPSR写进新值。
(4)MRC协处理器指令的目标寄存器为R15时,可以将协处理器产生的条件标志位的值传送到ARM处理器。
(5)在中断返回时,多寄存器加载指令可以将SPSR的值复制到CPSR中。