一百三十五、异常处理流程
135.1 arm处理器工作模式
135.2 异常源和异常模式关系
135.2.1 异常源
135.2.2 对应关系
异常模式 | 异常源 | |
---|
FIQ模式 | FIQ类型异常源 | 引发处理器进入FIQ模式 |
IRQ模式 | IRQ类型异常源 | 引发处理器进入IRQ模式 |
SVC模式 | 上电复位(RESET) | 引发处理器进入svc模式 |
| swi(软中断指令) | 引发处理器进入svc模式 |
undef模式 | 未定义异常源 | 引发处理器进入undef模式 |
abort模式 | prefetch abort | 引发处理器进入abort模式 |
| data abort | 引发处理器进入abort模式 |
135.2.3 总结
- 五种异常模式,对应七种异常源
- 异常源具有优先级,复位优先级最高
- 根据不同的异常源,进入不同异常模式,执行异常处理程序
135.3 异常处理流程(重点)
135.3.1 框图
135.3.2 保存现场(四大步三小步)
- 保存CPSR寄存器中的值,到SPSR_寄存器中
- 修改CPSR寄存器中的值
- 修改CPSR寄存器中的模式位,修改为对应的异常模式
- 修改CPSR寄存器中的T位,T=0为arm状态,执行arm指令集
- 根据需要,禁止相应的中断位
- 保存函数的返回地址,到LR寄存器中
- 修改PC指向异常处理程序的入口
135.3.3 恢复现场
- 将SPSR_寄存器中,恢复给CPSR寄存器
- 将LR寄存器中的值,恢复给PC
135.3.4 为什么引入异常向量表
- 问题:修改PC指向异常处理程序的入口 ==> 入口就是一个标签,标签就是函数名,每个人编写的函数名不一致
- 答:函数名不一致,每个函数名就是地址,arm公司设置异常向量表,通过操作一块地址空间
135.4 异常向量表
135.4.1 什么是异常向量表
- 异常向量表是一块寻址空间,这块寻址空间占用32字节,平均分成8份,每份占用4字节空间
- 异常向量表存放七种异常源,1份进行保留
- 异常向量表地址固定,不可以进行修改
- 通过指定异常向量表的基地址,根据偏移地址,可以找到对应的异常源
135.4.2 框图
135.4.3 软中指令
软中断指令码:swi
格式:swi 软中断号(0 ~ 0xffffff)====> 0 ~ 16,777,215
135.4.4 软中断代码编写
.text @文本段
.global _start @声明一个_start全局函数
_start: @指定汇编中函数入口
@0.构建异常向量表
b reset
b undef_interrupt
b software_interrupt
b prefetch_abort
b data_abort
b .
b irq
b fiq
reset:
@1.系统一上电处于SVC模式,初始化SVC模式栈指针0x40000800
ldr sp,=0x40000800
@2. 从SVC模式切换到user模式,初始化user模式栈指针0x40000700
msr cpsr,#0xD0
ldr sp,=0x40000700
@3.r0 = 0x1 r1 = 0x2
mov r0,#0x1
mov r1,#0x2
@4.执行软中断指令 swi 2 ====> 保存现场(四大步三小步)
swi 2
@ r0 = r0 + r1 = 0x3
add r0,r0,r1
b stop
undef_interrupt:
software_interrupt:
@ 压栈保存现场 r0 = 0x1 r1 = 0x2
stmfd sp!,{r0-r12,lr}
@3.r0 = 0x3 r1 = 0x4
mov r0,#0x3
mov r1,#0x4
@4. r0 = r0 + r1 = 0x7
add r0,r0,r1
@5. 出栈恢复现场
ldmfd sp!,{r0-r12,pc}^ @^:将SPSR_<MODE>寄存器中,恢复给CPSR寄存器
prefetch_abort:
data_abort:
irq:
fiq:
stop: @ 声明一个stop函数标签
b stop @ 跳转到stop标签下的第一条指令执行 相当于C语言中while(1)
.end