arm的异常处理过程分析

上传人:第*** 文档编号:118921296 上传时间:2019-12-30 格式:DOCX 页数:13 大小:341.56KB
返回 下载 相关 举报
arm的异常处理过程分析_第1页
第1页 / 共13页
arm的异常处理过程分析_第2页
第2页 / 共13页
arm的异常处理过程分析_第3页
第3页 / 共13页
arm的异常处理过程分析_第4页
第4页 / 共13页
arm的异常处理过程分析_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《arm的异常处理过程分析》由会员分享,可在线阅读,更多相关《arm的异常处理过程分析(13页珍藏版)》请在金锄头文库上搜索。

1、官网给出来的79移植手册(104),分析了在中移植的问题,想想从来没有认真的学习过的汇编,趁着这个机会复习复习吧。其实底层的东西才是创造力的心脏。其中的移植代码中存在的很多问题比如中断的关闭和开启,任务级别的情景切换,中断到任务的情景切换都是我们在平时移植中讲到,我也不在此强调了。在官网中提供的移植过程中存在异常处理机制,这个本不是在移植过程中考虑的,但是文档中确实提供了一个比较好的处理方式。我在此对这一段时间的学习做一个总结。首先需要了解的异常处理机制,异常是每一种处理器都必须考虑的问题之一,关键在于如何让处理,返回地址在什么位置都是需要考虑的,中支持7种异常,其中包括复位、未定义指令异常、

2、软中断异常、预取指令中止、数据中止、。每一种异常运行在特定的处理器模式下。我在此逐一的分析。一般异常发生后,都会进行一系列的操作,这些操作有一部分是自动完成,有一部分是需要我们程序员完成。首先说明会自动完成的部分,用结构手册中的代码描述如下:R14_ = 这个可以参看寄存器的说明,两个作用 = 4:0 = 5 = 0;指令 只有在复位和模式下才会关闭中断6 = 1;7 = 1;任何异常模式下都会关闭中断 = 从上面的代码中我们可以发现自动处理的过程包括如下:1、拷贝到2、设置适当的位:改变处理器状态进入状态;改变处理器模式进入相应的异常模式;设置中断禁止位禁止相应中断。3、更新,这个寄存器中保

3、存的是异常返回时的链接地址4、设置到相应的异常向量以上的操作都是自动完成,异常的向量表如下:返回地址问题异常的返回地址也是需要我们注意的地方,不同的异常模式返回地址也是存在差异的,这主要是因为各种异常产生的机理存在差别所导致的。这样我们的需要在异常进入处理函数之前或者在返回时调整返回地址,一般采用进入异常处理函数前进行手动调整。下面每一种异常R14保存的值都给了出来,其中也包含了自动处理的部分,根据保存的R14就可以知道怎样实现地址的返回。复位异常:可以看出该模式下的先对来说返回地址也比较简单,不需要做太多的描述。未定义的指令异常:返回的方式也比较简单:, R14软中断异常:返回的方式也比较简

4、单:, R14预取指令中止异常:返回需要做下面的调整:, R14, #4数据中止返回地址需要做下面的调整:如果需要重新访问数据则:, R14, #8如果不需要重新访问数据则:, R14, #4中断的处理过程:返回地址需要做下面的调整: 144中断:返回地址需要做下面的调整:, R14 4从上面的代码可以知道,对于每一种异常,保存的返回地址都是不一样的,一般都需要我们手动的跳转,当然调整的时机也需要我们选择,是在进入处理前跳转还是返回时调整都是需要我们程序员控制的。在 中对处理器的异常处理操作提供能更加详细的解释,每一种异常下的处理方式如下文描述:异常返回时另一个非常重要的问题是返回地址的确定,

5、在前面曾提到进入异常时处理器会有一个保存的动作,但是该保存值并不一定是正确的返回地址,下面以一个简单的指令执行流水状态图来对此加以说明。我们知道在架构里,值指向当前执行指令的地址加8处,也就是说,当执行指令A(地址0x8000)时,等于指令C的地址(0x8008)。假如指令A是“”指令,则当执行该指令时,会把(=0x8008)保存到寄存器里面,但是接下去处理器会马上对进行一个自动的调整动作:0x4。这样,最终保存在里面的是B指令的地址,所以当从返回时,里面正好是正确的返回地址。同样的调整机制在所有自动保存操作中都存在,比如进入中断响应时,处理器所做的保存中,也进行了一次自动调整,并且调整动作都

6、是0x4。下面,我们对不同类型的异常的返回地址依次进行说明:假设在指令A处(地址0x8000)发生了异常,进入异常响应后,上经过调整保存的地址值应该是B的地址0x8004。1、如果发生的是软件中断,即A是“”指令异常是由指令本身引起的,从中断返回后下一条执行指令就是B,正好是寄存器保存的地址,所以只要直接把恢复给。 , 2、发生的是 异常异常是由指令本身引起的,从异常返回后下一条执行指令就是B,正好是寄存器保存的地址,所以只要直接把恢复给。 , 3、发生的是或中断因为指令不可能被中断打断,所以A指令执行完以后才能响应中断,此时已更新,指向指令D的地址(地址0x800C),上经过调整保存的地址值

7、是C的地址0x8008。中断返回后应该执行B指令,所以返回操作是: , , #44、发生的是 异常该异常并不是处理器试图从一个非法地址取指令时触发,取出的指令只是被标记为非法,按正常处理流程放在流水线上,在执行阶段触发 异常,此时上经过调整保存的地址值是B的地址0x8004。异常返回应该返回到A指令,尝试重新取指令,所以返回操作是: , , #45、发生的是“ ”访问存储器时触发该异常,此时指向指令D的地址(地址0x800C),上经过调整保存的地址值是C的地址0x8008。异常返回后,应回到指令A,尝试重新操作存储器,所以返回操作是: , , #8以上就是异常的操作部分,接下来就是程序员应该完

8、成的操作。1.由于会自动跳转到对应的异常向量中,因此只需要在在各个异常向量中存放对应的操作,最简单的都是存放一个B指令跳转到对应的异常处理函数的操作即可。但由于B指令的跳转返回只有32M,而异常处理函数的地址可能会超过32M,因此可以采用另一种方式实现方式:在异常向量中保存一条指令 ,其中的中就保存了异常处理函数的地址,当然的相对地址要小于32M。这样也就解决了跳转范围的问题。2.接下来就是异常处理函数对应的操作,可以在进入异常处理之前就进行返回地址的调整,这样后面就不用进行处理啦,当然也可以在返回过程中再调整。一般都是在这个过程中进行调整。进行压栈操作,保存对应的环境变量。调用实际的处理过程

9、等。3.出栈,恢复的状态和寄存器的值。由于第一步中已经调整好返回地址,这一步不需要再次调整。当然如果之前没有调整,这里则需要进行相应的调整。在的官网移植中采用通用异常处理函数的方式实现异常的处理,下面我们来分析其中的部分代码:首先是处理器部分的移植,包括异常向量、异常的号,存储异常处理函数地址的地址等:/*的异常号,支持7种类型的异常,每一种异常都存在一个号*/0x00 0x010x02 0x030x040x050x060x070x08/*异常向量地址*/(* 0x04 + 0x00)0x00(* 0x04 + 0x00)0x04(* 0x04 + 0x00)0x08( * 0x04 + 0x

10、00)0x0c(* 0x04 + 0x00)0x10/*这个异常是中不支持的异常*/(* 0x04 + 0x00)0x14(* 0x04 + 0x00)0x18(* 0x04 + 0x00)0x1c/*存储异常处理函数地址的地址*/* */(* 0x04 + 0x20)0x20(* 0x04 + 0x20)0x24(* 0x04 + 0x20)0x28( * 0x04 + 0x20)0x2c(* 0x04 + 0x20)0x30(* 0x04 + 0x20)0x34(* 0x04 + 0x20)0x38(* 0x04 + 0x20)0x3c/*存储在异常向量中的内容,实质上是 ,0x18的机器

11、码*/0/* */059018异常的初始化函数,首先,完成了在异常向量中存储指令的操作,采用机器码的形式就能避免直接访问寄存器什么的,其次,完成在固定的地址处存放对应异常处理函数的地址。其中采用了赋值的形式也是需要注意的,采用的强制类型转换和指针相结合的形式。保证了是修改地址处的内容。而不是修改地址。/*初始化异常中断向量*/ ()/*是对应中断向量表的地址是保存了对应的(实质上是一个指令)实质上就是在异常向量中存放了 , #0x18,也就是让指向对应的异常处理地址中的内容,也就是实现到实际处理函数的跳转。异常处理地址中存储了实际的异常处理函数的地址其他的异常也有相同的操作,是一个指令的机器码形式*/(*(32U *)=;(*(32U *)= (32U);(*(32U *)=;(*(32U *)= (32U);(*(32U *)=;(*(32U *) = (32U);(*(32U *)=;(*(32U *)= (32U);(*(32U *)=;(*(32U *)= (32U);

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 规章制度

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号