最简洁的中断现场保护

 阅读韦老师的中断现场保护和恢复代码,感觉下面红色部分的代码似乎用不到,因为恢复现场的时候,lr的内容早就放在堆栈里面,并且要推送到pc了,我把下面代码的红色部分去掉,做实验,可以顺利进出中断,可见这几句话对中断现场的保护和恢复没起到作用的,修改后的代码我用蓝色字体标出,是保护现场需要的最小系统。顺便提一下,arm中的pc寄存器并不是代表当前执行的指令地址,而是取指地址,因为arm采取流水线技术,同一个时间PC在取指,PC-4在译码,PC-8在执行,如果中断发生,正在执行的指令要执行完,这是原子操作,不可打断的,然后才跳入0x00000018(中断向量入口PC),所以如果要恢复现场,就必须跳回刚刚执行的指令的下一条指令,也就是PC-4,我们的LR寄存器起到的作用就是连接作用,什么连接呢?中断发生瞬间的PC值记录到LR中,以便于中断处理完后能恢复到下一条指令去,这就是中断处理前与处理后的连接关系。通过上述讨论,我们发现,    sub  lr,lr,#4 可以这样替换:    sub  lr,pc,#4 ,我用实验验证了一下,两者完全等价。
原来的代码:
HandleIRQ:                                               @HandleIRQ开始的代码用于处理中断

       sub  lr,lr,#4                                        @计算中断处理完毕后的返回地址

       stmdb      sp!,{r0-r12,lr}                     @保存使用到的寄存器                                                                                         

      ldr   lr,=int_return                                @设置调用ISR即EINT_Handle函数后的返回地址

      ldr pc,=EINT_Handle                           @调用中断服务函数,在interrupt.c中

int_return:

       ldmia      sp!,{r0-r12,pc}^    @中断返回,^表示将spsr的值复制到cpsr


修改后的代码:
  HandleIRQ:                                      @HandleIRQ开始的代码用于处理中断

       sub lr,lr,#4                                 @计算中断处理完毕后的返回地址

       stmdb      sp!,{r0-r12,lr}              @保存使用到的寄存器                                                                                   

       bl EINT_Handle                          @调用中断服务函数,在interrupt.c中  

       ldmia      sp!,{r0-r12,pc}^            @中断返回,^表示将spsr的值复制到cpsr

也可以是:

  HandleIRQ:                                      @HandleIRQ开始的代码用于处理中断

       sub lr,pc,#4                                 @计算中断处理完毕后的返回地址

       stmdb      sp!,{r0-r12,lr}              @保存使用到的寄存器                                                                                   

       bl EINT_Handle                          @调用中断服务函数,在interrupt.c中  

       ldmia      sp!,{r0-r12,pc}^            @中断返回,^表示将spsr的值复制到cpsr
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值