7种异常源:
异常优先级
异常处理——ARM核自动完成部分:
当异常产生时, ARM core会自动完成下面的工作
1、R14_< exception_mode > = return link //确定返回地址,并保存
2、SPSR_< exception_mode > = CPSR
3、修改CPSR相应的位
(1)CPSR[4:0] = exception mode number //切换到相应异常的工作模式
(2)CPSR[5] = 0 ; //进入ARM状态
(3)If ==Reset or Fiq then //只有在复位和FIQ模式下才会关闭FIQ中断
CPSR[6] = 1 ;
CPSR[7] = 1 ; //任何异常模式下都会关闭IRQ中断
4、PC = exception vector address //PC跳到异常向量入口处
异常处理——我们需要完成的部分
2.1 建立异常向量表
_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:
.long undefined_instruction
_software_interrupt:
.long software_interrupt
_prefetch_abort:
.long prefetch_abort
_data_abort:
.long data_abort
_not_used:
.long not_used
_irq:
.long irq
_fiq:
.long fiq
异常向量表:
2.2 异常处理
进栈保存现场(需提前申请堆栈)
处理异常
出栈恢复现场
Software_Interrupt:
ldr sp,=stack_base
stmfd sp!,{r0-r12,lr}
mov r0,lr
sub r0,#4
ldr r1,[r0]
bic r1,#0xFF000000
cmp r1,#2
bleq do_swi
ldmfd sp!,{r0-r12,pc}^
返回地址:
异常发生时,处理器会把当前PC的值保存到LR_< exception_mode >中并自动做LR = LR – 4的操作 ,需要注意的时,
此时LR的值并不一定是正确的异常返回地址,在不同的模式下需要做一定的处理才能正确返回
.text
@.global _start
_start:
b reset @0x00
ldr pc, _Undefined_Instruction @0x04
ldr pc, _Software_Interrupt @0x08
ldr pc, _Prefetch_Abort @0x0C
ldr pc, _Data_Abort @0x10
ldr pc, _Rserved @0x14
ldr pc, _IRQ @0x18
ldr pc, _FIQ @0x1C
_Undefined_Instruction:
.long Undefined_Instruction
_Software_Interrupt:
.long Software_Interrupt
_Prefetch_Abort:
.long Prefetch_Abort
_Data_Abort:
.long Data_Abort
_Rserved:
.long Rserved
_IRQ:
.long IRQ
_FIQ:
.long FIQ
reset:
mrs r5, CPSR
ldr r6,=0xFFFFFFE0
and r5,r6
orr r5,#0x10
msr CPSR, r5
mov r0, #0x0C
mov r1, #0x0C
mov r2, #0x0C
swi #02
mov r3, #0x0c
Undefined_Instruction:
mov r1,#2
Software_Interrupt:
ldr sp,=stack_base
stmfd sp!,{r0-r12,lr}
mov r0,lr
sub r0,#4
ldr r1,[r0]
bic r1,#0xFF000000
cmp r1,#2
bleq do_swi
ldmfd sp!,{r0-r12,pc}^
do_swi:
mov r0, #0x12
mov r1, #0x23
mov r2, #0x34
mov pc,lr
Prefetch_Abort:
mov r3,#4
Data_Abort:
mov r4,#5
Rserved:
mov r5,#6
IRQ:
mov r6,#7
FIQ:
mov r7,#8
.data
stack_end:
.space 200
stack_base:
.end