[ZLG-ARM] 请教,异常/跳转时 PC值的一些疑问.

[复制链接]
2839|4
 楼主| gofayao 发表于 2007-3-21 00:16 | 显示全部楼层 |阅读模式
抄入书上内容如下:<br /><br />------------------------------------------------------------------<br />|&nbsp;异常或入口&nbsp;|&nbsp;&nbsp;&nbsp;返回指令&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;之前的状态&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;ARM&nbsp;r14_x&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Thumb&nbsp;r14_x&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;MOV&nbsp;&nbsp;PC,R14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;SWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;MOVS&nbsp;PC,R14_svc&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;未定义指令|&nbsp;&nbsp;MOVS&nbsp;PC,R14_und&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;预取指中止|&nbsp;&nbsp;SUBS&nbsp;PC,R14_abt,#4&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;FIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;SUBS&nbsp;PC,R14_fiq,#4&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;IRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;SUBS&nbsp;PC,R14_irq,#4&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;数据中止&nbsp;&nbsp;|&nbsp;&nbsp;SUBS&nbsp;PC,R14_abt,#4&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC+8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;PC+8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />------------------------------------------------------------------<br /><br />Ps:表格内,那个“之前状态”栏的PC应该代表当前执行指令地址,而不是代表“预取指”的PC,这个是书上搞错了,好像很多书都比较混用这两个PC.<br /><br /><br /><br />从上面这个表可以看出:<br />BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行BL的下一条指令<br />SWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行SWI的下一条指令<br />未定义指令&nbsp;&nbsp;&nbsp;返回后执行未定义指令的下一条指令<br />预取指中止&nbsp;&nbsp;&nbsp;返回后执行继续执行一遍预取指中止指令<br />FIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行被FIQ中断的指令<br />IRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行被IRQ中断的指令<br />数据中止&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行数据中止指令的下一条指令<br /><br />疑问:<br />&nbsp;&nbsp;&nbsp;&nbsp;1.为什么&nbsp;&nbsp;数据中止异常&nbsp;r14值为PC+8,而不是PC+4呢?<br />&nbsp;&nbsp;&nbsp;&nbsp;2.为什么&nbsp;&nbsp;数据中止异常&nbsp;返回后是执行下一条指令,而不是和预取指中止&nbsp;一样重新执行一遍数据中止指令呢?<br /><br />望各位大侠&nbsp;讲解讲解,谢谢!!<br />
 楼主| gofayao 发表于 2007-3-21 10:05 | 显示全部楼层

自己顶个先

  
zlgARM 发表于 2007-3-21 10:20 | 显示全部楼层

RE

gofayao:<br />&nbsp;&nbsp;&nbsp;&nbsp;《ARM&nbsp;嵌入式系统基础教程(第一版)》的P48,写明了数据中止异常返回时,是R14-8,也就是说,继续重试被中止的指令。您看的那本书可能有笔误。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;之所以数据中止异常入口的R14是PC+8,是因为数据中止异常是在“导致异常的指令”的“下一条指令”处发生的。<br />
 楼主| gofayao 发表于 2007-3-21 12:05 | 显示全部楼层

看了一下,是那个电子档的笔误,书上是正确的.

刚看了一下&nbsp;ADS&nbsp;developer&nbsp;guide,应该这个才是正确的.<br /><br />&nbsp;------------------------------------------------------------------<br />|&nbsp;异常或入口&nbsp;|&nbsp;&nbsp;&nbsp;返回指令&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;之前的状态&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;ARM&nbsp;r14_x&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Thumb&nbsp;r14_x&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;MOV&nbsp;&nbsp;PC,R14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+2&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;SWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;MOVS&nbsp;PC,R14_svc&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+2&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;未定义指令|&nbsp;&nbsp;MOVS&nbsp;PC,R14_und&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+2&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;预取指中止|&nbsp;&nbsp;SUBS&nbsp;PC,R14_abt,#4&nbsp;|&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;FIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;SUBS&nbsp;PC,R14_fiq,#4&nbsp;|&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;IRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;SUBS&nbsp;PC,R14_irq,#4&nbsp;|&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+4&nbsp;&nbsp;&nbsp;|<br />|------------|---------------------|--------------|----------------|<br />|&nbsp;&nbsp;数据中止&nbsp;&nbsp;|&nbsp;&nbsp;SUBS&nbsp;PC,R14_abt,#8&nbsp;|&nbsp;当前指令+8&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;当前指令+8&nbsp;&nbsp;&nbsp;|<br />&nbsp;------------------------------------------------------------------<br /><br /><br />从上面这个表可以看出:<br />BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行BL的下一条指令<br />SWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行SWI的下一条指令<br />未定义指令&nbsp;&nbsp;&nbsp;返回后执行未定义指令的下一条指令<br />预取指中止&nbsp;&nbsp;&nbsp;返回后执行重新执行一遍预取指中止指令<br />FIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行被FIQ中断的指令<br />IRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行被IRQ中断的指令<br />数据中止&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行重新执行一遍数据中止指令<br />
ahyjj 发表于 2007-11-8 14:36 | 显示全部楼层

到底该是怎样?

以下是一个网友对arm异常出/入口的理解:<br />——————————————————————————————————<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arm异常返回小议<br />&nbsp;初学ARM,可能会被异常返回这个东西搞得头大。一会儿直接MOV&nbsp;PC,LR,一会儿LR-4,甚至有时要LR-8。为什么要-4,又或者为什么要-8?<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;当然了,如果你只是简单地想编个程序,基本上照抄ARM公司给的范例就可以了。但是凡事总想知道个所以然来,所有在这里简单地想议一议ARM的异常返回,到底为什么要-4,为什么要-8。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;想了解这些,至少要了解以下几个方面的问题:一、异常的种类。什么行为导致了异常,这一点非常重要,它关系到产生异常的指令是否要重新执行一遍,如果要重新执行,LR就要多减一个4(4字节,一个指令增量),这样PC才能指向你要重新执行的指令。二、异常发生时,PC值有没有更新?这一点也非常重要,如果PC值没有更新,LR就要少减一个4,如果PC值更新了,就要多减一个4。为了弄懂这一点,需要我们去了解ARM指令执行过程,到底是什么时候更新的PC值。刚才好像想到还有一点,只是刚接了一个电话,忘了。汗!<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;当然,在了解上面所有问题之前,首先需要清楚的就是ARM7的“取指-&gt译码-&gt执行”三级流水线。另外,需要明白的还有一个就是在异常发生时,处理器已经做过了SUBS&nbsp;LR,PC,#4。也就是说,LR已经进行了一次减4。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;举一个最简单的例子:IRQ和FIQ(为啥举这个例子捏,因为,介个.....,别的异常我还没搞清楚哈!):<br /><br />首先是IRQ和FIQ发生在什么时候,这时候PC有没有更新。“通常处理器执行完当前指令后,查询IRQ中断引脚和FIQ中断引脚,并且查看系统是否允许IRQ中断和FIQ中断。如果有中断引脚有效,并且系统允许中断产生,处理器将产生IRQ异常中断或FIQ异常中断。”我们可以看到,当前指令(设该指令为I0)已经执行完毕,即使我们不知道指令执行过程,也可以猜到这时PC已经更新,系统即将执行下一条执行,设该指令为I1,PC应该是I3。另外,我们还应该知道中断时候的指令是否应该被重新执行。我们通过IRQ或FIQ发生时的情况可以知道,I0已经执行完毕,也就是说I0不需要重新执行。于是我们知道,异常返回时应该执行I1。而当前LR中存放的是什么呢?LR中存放的应该是PC-4,也就是I3前面一条指令I2,我们要执行I1,这时,就应该是MOV&nbsp;PC,I1。I1不合法啊,那就应该是I1=I2-4=LR-4。于是返回指令就是SUBS&nbsp;PC,LR,#4。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;以上就是俺一点心得,很小,但是得来的很不容易啊!现在ARM的资料很多,中用的很少,大家基本都是抄来抄去。翻了无数的参考书,查了很多论文,终于算是基本知道中断返回应该怎么做了。自己看书,周围基本没有人可以交流,不知道理解是不是对的,大家指正。另外,对其它几个异常产生的原因还不是非常了解,在此不敢妄自揣度,向大家请教!&nbsp;<br />——————————————————————————————————<br />按照这位网友的理解:<br /><br />BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行BL的下一条指令<br />SWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行SWI的下一条指令<br />未定义指令&nbsp;&nbsp;&nbsp;返回后执行未定义指令的下一条指令<br /><br />这和楼主的观点一样,其原因是“在异常发生时,PC值没有更新”<br /><br />FIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行被FIQ中断的下一条指令<br />IRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回后执行被IRQ中断的下一条指令<br /><br />这和楼住的观点都不同了,之所以返回时要执行”SUBS&nbsp;PC,R14_mode,#4&quot;&nbsp;<br />这条指令是因为异常发生后PC的值已经改变,当前被打断的指令已经执行完毕<br />PC已经预取了当前指令+&nbsp;12的那条指令,所以异常返回时要R14要多减一个4<br /><br />对于异常的出/入口问题一直是困扰初学ARM者一道难题,即时是周工推荐的好书《ARM嵌入式系统基础教程》也不够详细。我想有必要请周工专门为大家详细说明一下<br />1、异常发生时流水线中处于“执行”状态的指令是否可以得到充分执行完毕<br />2、异常发生时PC是否更新?<br /><br /><br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

34

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部