今天在板子上跑了一个INT0触发异常的小程序,主程序是一个WHILE循环,依次点亮0-2三只LED灯,ISR中只是简单的点亮第四个LED灯,以观查现象,用的S3C4510B,开发板上有四只LED灯。主要是学习异常进入及返回,现对今天的学习做个小总结,只是书和程序都在实验室里,手头没有什么资料可参考。
学习中我认为我应该注意的关健点:
一、配置各寄存器
AMR中的寄存器较多,但是也很有规律,参考手册即可。
二、保护现场及恢复现场的处理
当进入ISR中时,第一步要做的就是保存LR值,此处保存LR-4的值,待恢复时直接赋给PC,对此今天和几个人一起讨论了一下,发现有些人对于PC返回值还是不怎么清楚,这里简要记录一下:
对于BL、SWI等,PC<--LR
对于IRQ、FIQ等,PC<--LR-4
对于ABRT,PC<--LR-8
首先应知道一点,发生异常时,LR中存放的是PC-4,我发现书上都没有指明这一点,只是说当发生BL等跳转时LR用来备份PC,会让人以为LR中放的就是PC值;
其次脑中要有流水线的概念:
对于BL,SWI这些,跳转时该条指令已执行完毕,返回时应从该指令的下一条开始执行,所以应为PC<--LR,该条指令不应再被执行。
对于ABRT,返回时应是该指令,因为该指令需要重新执行,所以应为PC<--LR-8。
对于IRQ,FIQ等,是在该条语句执行前触发的,所以返回应为PC<--LR-4。
跳转时清楚当前PC所指向的位置就尤为重要,对于当要执行一条指令时,PC一定已指向其下一条的下一条指令,此时LR=PC-4。解决了这个疑惑,那么R0等寄存器的入栈及出栈就相对简单了,用STM和LDM指令就可以了。
三、0X18地址处的跳转指令
当触发INT0中断时,由硬件自动实现程序的跳转,强制PC指向中断向量表中INT0位置即0X18,在该位置处,存放一条跳转指令,因为用B或BL等跳转范围有限,所有选择用LDR指令,将LDR PC,[PC,38-18-8]构造成一条机器指令,在MAIN函数中存入0X18位置处。38为ISR入口地址。今天有人问我为什么要减8,我不知道我解释清楚没有,我的解释是:当中断触发后PC强制指向0X18处,此时流水线清空,对三级流水线来讲,当经过取指、译码后,要执行该指令时,PC已指向其下一条的下一条指令,即已+8,所以构造的指令中应-8。以前做51的时候,只是简单的放一条JMP指令即可,今天第一次尝试构造一条机器指令。
今天李明老师指出我回答问题时说的都是一些零零散散的点,没有总结出一二三点来,很没有条理性,我想如果给别人讲时,很可能会把别人弄晕,我已经充分认识到了这一点,比如说刚刚想写一个小总结,可是写着写着就有些杂乱了,这一点确实需要注意,写在这里,警醒自己。