ARM中断异常处理的返回

ARM中断异常处理的返回(转)  

 

作者:孙晓明,华清远见嵌入式学院讲师。

举个小例子,下面是一段ARM汇编代码:

地址

指令

0x3000

BL add

0x3004

MOV r0,#0

0x3008

MOV r1,#1

0x300C

MOV r2,#2

AREA test,CODE,READONLY
    ENTRY
    Start
         MOV r0,#1
         MOV r1,#1
         BL add
         MOV r0,#0
         MOV r1,#1
    Add
         ADD r0,r0,r1
         MOV r0,r0,r1
         END

当0x3000处的BL指令执行时,会把PC(=0x3008)保存到LR寄存器里面,也就是LR=0x3008。接下来处理器会立即对LR进行一个自动的更新动作:LR=LR-0x4,这样,LR里面的地址为0x3008 – 0x4 = 03004,它是指令”MOV r0,#0”的地址,所以当从子程序add返回时,LR里面正好是正确的返回地址。既是下一条要执行的指令的地

一、中断异常处理函数调用
异常就是正在执行的指令,由于各种软件或硬件故障被打断,比如,在读数据或指令时,访问存储器失败、产生了一个外部硬件中断等。当这些情况发生时,在ARM系统里,由异常和中断处理程序做出相应的处理,当处理完成后,要返回到被中止的指令,使被中止的指令能够继续正常执行下去。因此,确定异常和中断处理程序的返回地址是一个非常重要的问题。

1、中断处理

当外部中断IRQ和FIQ(Fast Interrpt Request,快速中断请求)发生时,ARM核完成一部分工作。当然,这些工作是任何异常发生时都必须要做的,所以ARM处理器就会自动带我们完成。 其它重要的工作,必须由程序员来完成。ARM处理器处理的事包括从用户模式切换到IRQ模式、状态寄存器值的变化及跳转。比如说,处理器自动跳转到从0x0地址开始的异常中断向量表的0x18处,在向量表的0x18处,最简单的指令为”B HandlerIRQ”。

那程序员所要关心的就是实现具体的异常处理程序(HandlerIRQ)。当用ARM汇编语言实现HandlerIRQ函数的时候,如何确定HandlerIRQ函数正确地返回地址,使被中止的指令能够继续正常执行下去。

比较常用的中断处理程序结构如下:

HandlerIRQ ;中断响应,从向量表直接跳来

SUB r14,r14,#4 ;计算返回地址

STMFD r13,{r0-r3,r14} ;保护现场,一般只需要保护{r0-r3,lr}

BL irqHandler ;跳到具体的异常处理函数

LDMFD r13,{r0-r3,pc}^ ;恢复现场

有程序可以看出,通过”SUB R14,R14,#4”计算中断函数的返回地址。那有人一定会问,为什么计算返回地址的时候要减去4呢?

地址

指令

0x3000

BL add

0x3004

MOV r0,#0

0x3008

MOV r1,#1

0x300C

MOV r2,#2

我们看上个表,比如在执行地址为0x3004的move指令时,突然来了一个IRQ中断,这个中断打断了move指令的执行,这个时候就要去跳转到异常处理函数,之后还要返回0x3004地址重新执行move指令。当中断发生时,LR里面保存了用户模式下PC的值,那么当执行地址为0x3004的move指令时,PC的值应该是0x300C,前面介绍过,当发生跳转时,处理器会对LR进行一个自动的更新动作:LR=LR-0x4,这样LR里面的地址是0x300C-0x04=0x3008。但是0x3008并不是我们要的地址,因为中断发生在地址为0x3004的move指令执行的时候,所以中断处理完后应该返回这个地址。 这就是在计算返回地址的时候LR减去4的原因。对于FIQ中断和预取指中止异常,计算返回地址方法和IRQ相同。

我的理解:本身PC总是指向当前指令的下两条指令的地址,PC的值为当前指令的地址值加8个字节。发生跳转时,LR=LR-04,所以子程序返回时处理器自动计算LR=LR+08-04(LR+04),刚好是执行下一条指令。而中断后是要返回发生中断的当前指令继续执行,所以应该在LR返回后再减去一条指令地址04,即LR=LR-04。

以下我的整理:

2 、ARM处理器对异常的响应步骤:

a. 保护LR;

b. 将CPSR复制到相应的SPSR中;

c. 根据异常类型强制设置CPSR的运行模式位;

d. 跳转异常处理程序。

3、 ARM处理器对异常的返回步骤:

a. 回复LR,LR减去相应的偏移量后送到PC;

b. 将SPSR复制回CPSR中;

c.清楚中断禁止位。

二、各中断类型及优先级和返回值:

1、FIQ(Fast Interrupt Request)

   FIQ异常是为了数据传输或通道处理而设计的。CPSR中的F位:=1 禁止FIQ中断,=0允许中断。只能在特权模式下才能改变F的状态。可由外部将nFIQ引脚输入低电平也能产生FIQ。返回指令: SUBS PC,R14_fiq,#4.

2、IRQ(Interrupt Request)

  IRQ异常属于正常的终端请求,可以在nIRQ引脚输入低电平产生。CPSR中的I位: =1 禁止IRQ中断,=0允许IRQ中断,只能在特权模式下才能改变I的状态。返回指令:SUBS PC,R14_irq,#4.

3、Abort:中止

  产生中止异常意味着对存储器的访问失败。

a:指令预取中止:发生在指令预取时。  中断后PC=PC+8,返回指令:SUBS PC,R14_abt,#4.

b:数据中止:发生在数据访问时。         中断后PC=PC+12,返回指令:   SUBS PC,R14_abt,#8.

4、Software Interrupt

 SWI用于进入管理模式,用于请求执行特定的管理功能。返回地址:MOV PC,R14_svc.

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值