一百三十五、异常处理流程
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 resetb undef_interruptb software_interruptb prefetch_abortb data_abortb . b irqb 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, r1b stopundef_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