依据反常类型的不同,回来的办法也不同。反常形成下一条指令要从相应的向量表进口读取。
1 处理器对反常的反响
发生反常时,处理器采纳如下动作:
1. 将 CPSR 复制到相应的 SPSR 中。 这会保存当时形式、中止屏蔽和条件符号。
2. 转至ARM状况。
3. 更改相应的 CPSR 形式位,以便:
- 更改为恰当的形式,并在该形式的相应编组寄存器中进行映射。
- 禁用中止。发生任何反常时,都会禁用 IRQ。 在复位时发生 FIQ,会禁用 FIQ。
4. 将相应 LR 设置为回来地址。
5. 将 PC 设置为反常的向量地址。
2 从反常处理程序的回来
从反常中回来的办法取决于反常处理程序是否运用仓库操作。 不管是否运用,要回来到反常发生处持续履行,反常处理程序有必要:
- 从相应 SPSR 康复 CPSR
- 运用相应 LR 中的回来地址康复 PC。
关于不需要从仓库中康复方针形式寄存器的简略回来,反常处理程序可经过履行具有以下设置的数据处理指令来完结这些操作:
- 设置 S 符号
- PC 作为方针寄存器。
所需的回来指令取决于反常的类型。
留意,不必从复位处理程序回来,由于复位处理程序直接履行主代码。
处理反常时,假如反常处理程序进口代码运用了仓库来存储有必要保存的寄存器,则可经过运用带 ^ 限定符的加载多个指令来回来。 反常处理程序可运用一条指令回来,例如运用:
LDMFD sp!,{R0-R12,pc}^
为此,反常处理程序有必要将以下内容保存到仓库中:
- 调用处理程序时运用的一切作业寄存器
- 为发生与数据处理指令相同的作用而修正的链接寄存器。
^ 限定符指定从 SPSR 康复 CPSR。
留意:不能运用任何 16 位 Thumb 指令从反常回来,由于这些指令无法康复 CPSR。
3 回来地址和回来指令
发生反常时由程序计数器指向的实践方位取决于反常的类型。回来地址或许不必是程序计数器指向的下一条指令。假如反常发生在 ARM 状况,处理器则将 (PC+4) 存储在 lr_ mode。
下面较具体地说明晰每一种反常类型怎么从处理代码正确回来的指令。
3.1 从 SWI 和 未定义指令处理程序回来
SWI 和未定义指令反常是由指令自身形成的,因而,处理反常时,程序计数器坚持不变(预取指就失利了)。处理器将 (PC+4) 存储在 lr_ mode 中。因而使 lr_mode 指向下一条要履行的指令。要从 lr 中康复程序计数器,则运用:
MOVS pc, lr
从处理程序回来控制权。
将回来地址推入堆中并在回来时将其弹出的处理程序进口和出口代码为:
STMFD sp!,{reglist,lr}
;…
LDMFD sp!,{reglist,pc}^
3.2 从 FIQ 和 IRQ 处理程序回来
履行完每一条指令后,处理器检测中止管脚是否为 LOW(电平),以及 CPSR中止禁用位是否为铲除。成果,仅在程序计数器被更新后才发生 IRQ 或 FIQ 反常。处理器将 (PC+4) 存储在 lr_mode 中。使 lr_mode 指向发生反常时没有履行的指令的下一条指令。处理程序完结后,有必要从 lr_mode 指向发生反常时没有履行的指令处持续运转。该持续履行地址较 lr_mode 中的地址少一个字(四个字节),因而,其回来指令为:
SUBS pc, lr, #4
将回来地址推入堆中并在回来时将其弹出的处理程序进口和出口代码为:
SUB lr,lr,#4
STMFD sp!,{reglist,lr}
;…
LDMFD sp!,{reglist,pc}^
3.3 从预取中止处理程序回来
假如处理器企图在不合法地址取指令,则该指令被标志为无效。持续履行已经在流水线中的指令至遇到发生“预取中止”处的无效指令停止。如有将虚拟存储器方位映射到该物理存储器的指令,反常处理程序将无映射联系的指令装入物理存储器并运用 MMU。然后,处理程序有必要回来,再次使着运转发生反常的指令。现在装入并履行指令。
由于宣布预取中止时程序计数器还没有被更新,所以 lr_abt 指向发生反常的下一条指令。处理程序有必要回来至 lr_ABT-4 的指令,请运用下列指令:
SUBS pc,lr, #4
将回来地址推入堆中并在回来时将其弹出的处理程序进口和出口代码为:
SUB lr,lr,#4
STMFD sp!,{reglist,lr}
;…
LDMFD sp!,{reglist,pc}^
3.4 从数据中止处理程序回来
当装入或存储指令企图拜访存储器时,程序计数器被更新。(PC+4) 的存储值指向发生反常地址处的第二条指令。MMU(假如有)将相应地址映射至物理存储器,处理程序有必要回来到本来中止的指令,以便进行第2次履行测验。因而,回来地址较 lr_abt 中少两个字(八个字节),运用如下回来指令:
SUBS pc, lr, #8
将回来地址推入堆中并在回来时将其弹出的处理程序进口和出口代码为:
SUB lr,lr,#8
STMFD sp!,{reglist,lr}
;…
LDMFD sp!,{reglist,pc}^