对cpsr的操作是采用“读取-修改-写入”的方式。即先用mrs读出,再修改,最后用msr写入cpsr。注意上面写入时用的是cpsr_cxsf,下划线_后面的表示的是“域”的意思,用于设定cpsr中需要操作的位。
c - control field mask byte (PSR[7:0]) 控制位域
x - extension field mask byte (PSR[15:8])
s - status field mask byte (PSR[23:16)
f - flags field mask byte (PSR[31:24]).
比如 msr cpsr_c, r1 表示只修改控制位,即cpsr的低8位。具体的可查看cpsr各位的定义。
12. 异常服务的响应过程
出现一个异常,arm处理器会执行以下几个步骤:
A. 将下一条指令存入相应的lr里,以便程序从异常返回时能从正确的位置开始。
B. 将cpsr复制到相应的spsr。
C. 强制设置cpsr的运行模式位
D. 强制从异常向量地址取得下一条指令
Ok,经过以上步骤,就进入了异常里。以上步骤都是处理器自动执行的,不需要软件干涉。从上面的D步骤起,我们在向量地址上放置跳转指令,那么程序就可以跳到相关的处理程序里了。
我们顺着书上的例子走一遍吧。
(1)FIQ
A. 产生FIQ中断时,cpu自动跳到0x0000001c这个地址去执行代码。还记得中断向量表吧,里面这个地址的指令是 b
HandlerFIQ 。即要跳入HandlerFIQ 里了。
B. HandlerFIQ在哪里呢?
程序里有一段宏定义如下