×
单片机 > 单片机程序设计 > 详情

ARM各种异常返回地址的计算

发布时间:2024-05-18 发布时间:
|

首先,给出ARM的三级流水线结构图,这是后面分析的基础。

上图中最左侧为指令的地址,根据三级流水线结构,当PC=0X3008是时,正在执行的的指令是地址为0X3000的这条指令。


在分别讲解各种异常之前,有一条总的原则就是:无论发生什么异常(除复位),内核总是会首先将 PC-4 放到LR寄存器中。


1.复位异常


复位异常中断处理程序不需要返回。在复位异常中断处理程序开始整个用户程序的执行,因而它不需要返回。


2.未定义指令异常


指遇到了一条没有定义的指令导致执行时无法执行。


未定义指令异常中断是由当前执行的指令自身产生的,当产生中断时,程序计数器PC的值还未更新(未更新的意思就是PC还没有加4 呢);


以上面的流水线结构为例,地址为0X3000的指令(即第一条指令)执行时产生未定义异常,这时PC = 0X3008,内核将会把PC-4即0X3004放到LR_UND寄存器中。中断执行结束之后,我们实际上要执行的就是0X3004这条指令,所以直接用MOV PC,LR


3.软件中断异常


由指令SWI引起的,程序在执行这一指令后,进入异常中断。


同样,未定义指令异常中断是由当前执行的指令自身产生的,当产生中断时,程序计数器PC的值还未更新;


具体实例与未定义指令异常相同,不再赘述。


4.预取指异常


预取指异常与下面的数据访问异常是比较难以区分的。

由程序存储器引起的中止异常叫做预取指中止异常;

由数据存储器引起的中止异常叫做数据中止异常。


虽然预取指异常在取指阶段就会被标记出来,但是一定要到执行该指令的时候才会出现异常,因为这条指令可能根本就没有机会运行。当然数据中止异常也是要到指令执行阶段才出现的。


这两者之间还有一点共同点就是,当出现异常后,要重新再执行一次这条指令,这也是与其他异常不太一样的地方。


这两者之间的重要区别就在于:预取指异常是由于指令自身引起的,所以当产生中断时,程序计数器PC的值还未更新;但是数据中止异常的产生是由ALU产生的,当产生中断时,PC的值已经更新了(比如说0X3000产生数据异常,中断产生时,PC=0X000C了已经)!!


言归正传,举例说明。地址为0X3000的指令执行时产生预取指异常,这时PC = 0X3008,内核将会把PC-4即0X3004放到LR_ABT寄存器中。中断执行结束之后,我们实际上要执行的就是0X3000这条指令,所以用 SUBS PC,LR,#4


5.数据中止异常


数据中止异常就是在执行指令时数据出现错误。


再次强调,数据访问异常中断由当前执行的指令在ALU里执行时产生,当数据访问异常中断发生时,程序计数器pc的值已经更新。


举例。地址为0X3000的指令执行时产生数据中止异常,这时PC = 0X300C,内核将会把PC-4即0X3008放到LR_ABT寄存器中。中断执行结束之后,我们实际上要执行的就是0X3000这条指令,所以用 SUBS PC,LR,#8


6.中断请求(IRQ)异常


在此不解释何为中断请求异常。

注意,产生中断请求异常时,程序计数器pc的值也已经更新!


举例。地址为0X3000的指令执行时产生数据中止异常,这时PC = 0X300C,内核将会把PC-4即0X3008放到LR_IRQ寄存器中。中断执行结束之后,我们实际上要执行的就是0X3004这条指令,所以用 SUBS PC,LR,#4


7.快速中断(FIQ)请求异常


与IRQ异常基本相同,不再赘述。


总结:


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析