您的位置:首页 > 其它

最简洁的中断现场保护

2016-07-10 22:23 267 查看
阅读韦老师的中断现场保护和恢复代码,感觉下面红色部分的代码似乎用不到,因为恢复现场的时候,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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: