arm体系结构学习笔记 part3 -- 异常处理机制

先来看看异常向量表:

 

这个表格给出了当异常发生时候的程序将跳转到的地址  以及跳转到该地址的同时arm核所处的异常模式
以未定义异常为例当arm核执行时遇到未定义的指令时  程序将自动跳转到异常向量表中的0x00000004地址处执行 并将处理器切换为未定义模式  与此同时其实arm核还完成了cpsr到spsr_und的备份以及设置异常处理完毕的返回地址保存到lr_und

而复位异常的跳转地址为0x0  这是每次系统重新加电的时候arm核总是从0x0地址开始取指令指令    而系统上电时系统所处的模式总是svc模式   

貌似有点忘了说了 异常向量表总共占用32个字节   总共有7个异常向量   0x00000014是保留的并未使用 所以是(4*7+4)BYTE

文字的说明貌似有点虚   看一下uboot中的第一阶段代码   也是uboot执行的入口:

 

 

看看这里的b start_code其实是处理复位异常因为异常向量表只有32字节大小,所以采用了跳转的方式来转到相应的异常处理函数。复位异常处理函数的代码如下采用B跳转   B指令跳转的空间为前后32MB范围内代码处于同一文件中几乎是紧挨在中断向量表之后 所以b指令跳转是无任何问题的:

 

其它的异常采用ldr pc,label   lable分别是    

_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

以_irq label为例  ldr pc, _irq   执行的是将irq的值赋给pc   irq的值为irq异常处理函数的地址

 

下面我们来实例解析一下未定义指令异常的处理机制先上代码:

第一步测试,主要做的是观察一下uboot下未定义指令执行时的情况:

makefile:

 

test.S:

 

这里0x77777777是一条未定义的指令   这个是别人测试的结果  

下载并测试的结果如下:

 

当arm执行未定义指令的时候   板子重启了    这个是uboot设定的对异常的处理    不做多余的展开了   看看下面改进的测试代码二  应该就能清楚了。

下面是第二份的测试代码:

宿舍停电了  代码没法测试了  先贴上来 明天补全测试

makefile:

 

vector.S:

 

mov sp, #0x32000000@这里要设置堆栈寄存器  因为切换到未定义指令异常前,arm处于svc模式,执行到未定义指令时,arm切换到了未定义模式,svc模式下的堆栈由uboot已经设置好,但是未定义模式下的堆栈并未设置,printf函数又需要用到堆栈,如果少了这条语句的话调用printf函数将失败。

 

loop:

    b loop

这里让开发板执行prinrf函数后停止  做个死循环

 

还有一点就是这段代码是与位置无关的代码  连接时随意指定text段的运行地址都可以。下载到开发板的时候只要下载到0x0处都可以执行。

test.S

 

测试的时候只要讲test.bin下载到0x30000000 vector.bin下载到0x0出   go 30000000 将会打印出   undefined instr.

附上下载测试结果:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值