1. 寄存器与工作模式
ARM可工作在7种不同的工作模式。异常模式下有各自的分组寄存器。
CPSR寄存器,控制工作模式,中断开关,以及标志位指示。
工作模式对应表。
2. 异常向量表
在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。V和中断向量表的对应关系如下:
V=0 ~ 0x00000000~0x0000001C
V=1 ~ 0xffff0000~0xffff001C
异常向量表的代码实现,nop部分需要用实际的异常处理代码替代。
.text
.global _start
_start:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction:
.word undefined_instruction
_software_interrupt:
.word software_interrupt
_prefetch_abort:
.word prefetch_abort
_data_abort:
.word data_abort
_not_used:
.word not_used
_irq:
.word irq
_fiq:
.word fiq
undefined_instruction:
nop
software_interrupt:
nop
prefetch_abort:
nop
data_abort:
nop
irq:
nop
fiq:
nop
任何异常发生时,以下步骤是硬件首先自动完成的
每次上电复位程序就进入了一次异常,复位异常硬件自动完成以下过程。可以看出,上电后中断都是关闭的,运行在ARM状态,SVC模式。而且复位中断也不必返回。
3. 中断处理,这里已SWI异常为例。
vector_swi:
/* 1.保存现场 */
ldr sp, =0x56000000
stmdb sp!, {r0-r12, lr} /* lr 保存swi 下一条指令的地址 */
/* 2.处理异常,这里的代码只是示例*/
mrs r0, cpsr
ldr r1, =swi_str
bl print_cpsr
/* 3.恢复现场*/
ldmia sp!, {r0-r12, pc}^ /* ^表示把SPSR_svc复制到CPSR */
关于保存/恢复现场,ARMv5_ARM中是这样讲的,其实STMFD和stmdb是一样的指令。
注意到上图中R14-4返回PC,这是因为进入/退出不同异常模式时的PC地址计算方法略有不同,具体如下图所示。