http://cbqcgq.blog.hexun.com/9178600_d.html
应该是这样的:
“将下一条指令的地址存入相应的连接寄存器LR,以便程序在处理异常返回时能从正确的位置重新开始执行。”这里的“将下一条指令的地址存入相应的连接寄存器LR”,说的把是寄存器pc当前值存入LR,也就是当前指令地址A+8存入了LR,那么如果处理完中断后照此返回的话,显然会跳过A+4这条指令而造成错误,因此需要人为将LR减4,也就是你在问题2中的这条语句:
SUB LR,LR,#4 ;计算返回地址
注意sub是减法不是加法……
另一方面,正如狗狗所说,某些异常是特殊的,对于这些特殊的异常而言,存入LR的值不是A+8而是A+4,那么这些异常处理函数就不需要再重新计算返回地址了。
原先我的理解是这样的:
1,假设当前是PC,PC-4,PC-8
2,发生中断,PC被取消,代之一中断服务程序的首地址指令,但是PC-4还在流水线中(就象排队的三个人,第一个找别人代替了,但是后面的反正不受影响)
3,由硬件将当前被中断的预取指令的下一条指令放进LR(所以资料上说是PC+4)
4,中断服务程序的首指令进入译码阶段
5,原来的那个PC-4进入执行阶段(三级流水线的缘故)
6,中断程序预取最后一条返回指令
7,预取程序空间中中断程序之后的非中断程序指令,仍然使用IRQ模式下寄存器
8,预取的中断程序指令进入执行阶段
9,中断程序结束,返回,当前PC=LR-4(LR为原来被中止取指的那条指令的下面一条指令),相减后,PC又指向了被中断的那条预取指令,再次预取,原来预取的中断程序下面的非中断程序指令因为处于IRQ状态,而程序已经中断返回之前模式,所以无效
10,如果在IRQ中断中预取的非中断程序是操作PC的指令怎么办?不会出现这样的情况,程序空间是连续的,中断处理程序之后紧接着的两条非中断处理程序指令不会莫名其妙地为操作PC的指令,即使它们是另外的中断服务程序的头两条指令,也没有影响。因为中断程序的头两条指令是保护PC指令(即计算返回地址)和堆栈操作指令,当预取堆栈操作指令时,正确的那个IRQ中断返回指令已经被执行,并且被执行的保护PC指令(MOV LR,LR,#4)没有执行对PC的操作,对程序无影响。
现在我的理解是这样的:
1,假设当前是PC,PC-4,PC-8
2,发生IRQ异常,执行保护操作,LR中保存将要执行指令的下一条指令
3,清空流水线
4,进入中断服务程序
5,待流水线填满,执行操作才被重新挂起(解释了ARM7为什么是0.9MIPS)
6,中断返回前,对LR处理,LR=LR-4,指向之前被清空的已译码指令
7,返回
8,重新对丢弃的前一次已译码指令取指
9,待流水线满,开始执行
我操他LP,很多书还没我翻译的好,下面这个才是完全正确的:
1,假设当前是PC,PC-4,PC-8
2,发生IRQ异常,执行保护操作,LR中保存由于FIQ或IRQ占先而没有被执行的指令的地址(即有些资料上把这个地址写成PC或者当前地址,很费解甚至误解)的下一条地址
3,清空流水线
4,进入中断服务程序
5,待流水线填满,执行操作才被重新挂起(解释了ARM7为什么是0.9MIPS)
6,中断返回前,对LR处理,LR=LR-4,指向之前被清空的已译码但没被执行的指令的地址
7,清空流水线,返回
8,重新对丢弃的前一次已译码指令取指
9,待流水线满,开始继续执行
用户1565581 2009-8-28 16:57
用户1565581 2009-8-28 16:53
用户111650 2007-12-18 17:40
请教:
⒈挂起,是把进程从内存转移到外存,你在第5点--待流水线填满,执行操作才被重新挂起.这里用"挂起"代表什么意思?
⒉还有第2点--发生IRQ异常,执行保护操作,LR中保存由于FIQ或IRQ占先而没有被执行的指令的地址(即有些资料上把这个地址写成PC或者当前地址,很费解甚至误解)的下一条地址.这里的"执行保护操作"能具体讲解一下吗?
⒊未定义指令异常和SWI异常的返回不需要进行LR的调整,这是为什么?