通过上图我们可以知道,CPSR记录了处理器当前工作的模式,FIQ、IRQ中断是否使能,指令带条件执行结果等信息。
下面我们详细来看看每一位分别代表什么意思:
A.条件代码标志
(N ) 运算结果的最高位反映在该标志位。对于有符号二进制补码,结果为负数时N=1,结果为正数或零时N=0;
(Z ) 指令结果为0时Z=1(通常表示比较结果“相等”),否则Z=0;
(C ) 当进行加法运算(包括CMN指令),并且最高位产生进位时C=1,否则C=0。当进行减法运算(包括CMP 指令),并且最高位产生借位时 C=0,否则C=1。对于结合移位操作的非加法/减法指令,C为从最高位最后移出的值,其它指令C通常不变;
(V)进行加法/减法运算,并且发生有符号溢出时V=1,否则V=0,其它指令V通常不变。
B. 中断禁止位包括I和F位
当I位置位时,IRQ中断被禁止;
当F位置位时,FIQ中断被禁止。
C.T位反映了正在操作的状态
当T位置位时,处理器正在Thumb状态下运行;
当T位清零时,处理器正在ARM状态下运行。
D.模式位
模式位包括M4、M3、M2、M1和M0,这些位决定处理器的操作模式。
10000 User mode ; 10001 FIQ mode; 10011 SVC mode ; 10111
Abort mode ; 11011 Undfined mode;
11111 System mode; 10110 Monitor mode; 10010 IRQ
注意:不是所有模式位的组合都定义了有效的处理器模式,如果使用了错误的设置,将引起一个无法恢复的错误
(5)SPSR 程序状态保存寄存器
每种异常都有自己的SPSR,在因为异常事件而进入异常时它保存CPSR的当前值,异常退出时可通过它恢复CPSR。
五、Thumb状态下的寄存器
ARM状态和Thumb状态之间寄存器的关系
Thumb状态寄存器与ARM状态寄存器有如下的关系:
Thumb状态R0~R7与ARM状态R0~R7相同;
Thumb状态CPSR和SPSR与ARM状态CPSR和SPSR相同;
Thumb状态SP映射到ARM状态R13;
Thumb状态LR映射到ARM状态R14;
Thumb状态PC映射到ARM状态PC(R15)。
注意: 在Thumb状态中,高寄存器(R8~R15)不是标准寄存器集的一部分
六、ARM异常处理
前面我们已经说过异常了,所谓的异常可以理解为CPU的正常执行被打断,而不得不去完成一些特殊的工作。有些同学可能感觉还是有点抽象,举个例子说明一下吧:假如你正在努力的写代码,这个时候你肚子饿了,必须得解决呀,你就停止写代码,去吃饭了,吃完饭你又继续写代码了,过了一会,你的瞌睡虫来找你了,必须得睡觉呀,都三天三夜没睡了。睡完之后,你又开始写代码。这里的肚子饿,瞌睡虫就可以理解成异常情况,必须得处理,处理完后还得恢复以前的状态。
那异常产生的时候,硬件上会自动做那些事情呢?注意是硬件自动做的哦,不需要我们介入的。
当一种异常发生时,硬件就会自动执行如下动作:
(1)将CPSR保存到相应异常模式下的SPSR中
(2)把PC寄存器保存到相应异常模式下的LR中
(3)将CPSR设置成相应的异常模式
(4)设置PC寄存器的值为相应处理程序的入口地址
可以总结如下图:
细心的同学就会发现,这里的PC寄存器的值不是应该指向正在执行的指令吗?为什么图中却指向了正在提起的指令,这里的“正在提取”又有什么含义呢?呵呵,这就涉及到流水线的问题了,关于流水线我们后面会介绍的。
这里我们还是先搞明白,异常产生的时候,硬件应该将PC值设为多少呢?要想明白这个问题,还必须先知道一个概念“异常向量表”。
ARM一共有5种异常模式,按道理,每一种异常模式都应该有一个唯一的入口地址。这些入口地址彼此相邻,我们一般称之为异常向量表。
当异常产生的时候,硬件会自动将PC的值设置为对应异常量的入口地址。具体异常向量表存放在什么位置,我们可以通过相关的协处理指令进行设置就可以了。这个我们在后期的课程中会讲到。
好了到这里,我们已经知道了,异常发生时,硬件都自动做了哪些事情。那异常返回的时候,硬件也会自动做一些事情吗?呵呵,答案是没有。异常返回的时候,程序员必须做如下事情:
异常返回
(1)从 SPSR_《mode》恢复CPSR
(2)从LR_《mode》恢复PC
这些事情产生的效果就是恢复现场哦。
本文出自 “嵌入式学习天地” 博客,请务必保留此出处
http://farsight.blog.51cto.com/1821374/1346676