打印
[ZLG-ARM]

请教,异常/跳转时 PC值的一些疑问.

[复制链接]
1744|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gofayao|  楼主 | 2007-3-21 00:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
抄入书上内容如下:

------------------------------------------------------------------
| 异常或入口 |   返回指令          |          之前的状态           |
|            |                     |  ARM r14_x   |  Thumb r14_x   |
|------------|---------------------|--------------|----------------|
|  BL        |  MOV  PC,R14        |     PC+4     |   PC+2         |
|------------|---------------------|--------------|----------------|
|  SWI       |  MOVS PC,R14_svc    |     PC+4     |   PC+2         |
|------------|---------------------|--------------|----------------|
|  未定义指令|  MOVS PC,R14_und    |     PC+4     |   PC+2         |
|------------|---------------------|--------------|----------------|
|  预取指中止|  SUBS PC,R14_abt,#4 |     PC+4     |   PC+4         |
|------------|---------------------|--------------|----------------|
|  FIQ       |  SUBS PC,R14_fiq,#4 |     PC+4     |   PC+4         |
|------------|---------------------|--------------|----------------|
|  IRQ       |  SUBS PC,R14_irq,#4 |     PC+4     |   PC+4         |
|------------|---------------------|--------------|----------------|
|  数据中止  |  SUBS PC,R14_abt,#4 |     PC+8     |   PC+8         |
------------------------------------------------------------------

Ps:表格内,那个“之前状态”栏的PC应该代表当前执行指令地址,而不是代表“预取指”的PC,这个是书上搞错了,好像很多书都比较混用这两个PC.



从上面这个表可以看出:
BL           返回后执行BL的下一条指令
SWI          返回后执行SWI的下一条指令
未定义指令   返回后执行未定义指令的下一条指令
预取指中止   返回后执行继续执行一遍预取指中止指令
FIQ          返回后执行被FIQ中断的指令
IRQ          返回后执行被IRQ中断的指令
数据中止     返回后执行数据中止指令的下一条指令

疑问:
    1.为什么  数据中止异常 r14值为PC+8,而不是PC+4呢?
    2.为什么  数据中止异常 返回后是执行下一条指令,而不是和预取指中止 一样重新执行一遍数据中止指令呢?

望各位大侠 讲解讲解,谢谢!!

相关帖子

沙发
gofayao|  楼主 | 2007-3-21 10:05 | 只看该作者

自己顶个先

使用特权

评论回复
板凳
zlgARM| | 2007-3-21 10:20 | 只看该作者

RE

gofayao:
    《ARM 嵌入式系统基础教程(第一版)》的P48,写明了数据中止异常返回时,是R14-8,也就是说,继续重试被中止的指令。您看的那本书可能有笔误。
     之所以数据中止异常入口的R14是PC+8,是因为数据中止异常是在“导致异常的指令”的“下一条指令”处发生的。

使用特权

评论回复
地板
gofayao|  楼主 | 2007-3-21 12:05 | 只看该作者

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

刚看了一下 ADS developer guide,应该这个才是正确的.

 ------------------------------------------------------------------
| 异常或入口 |   返回指令          |          之前的状态           |
|            |                     |  ARM r14_x   |  Thumb r14_x   |
|------------|---------------------|--------------|----------------|
|  BL        |  MOV  PC,R14        | 当前指令+4   |   当前指令+2   |
|------------|---------------------|--------------|----------------|
|  SWI       |  MOVS PC,R14_svc    | 当前指令+4   |   当前指令+2   |
|------------|---------------------|--------------|----------------|
|  未定义指令|  MOVS PC,R14_und    | 当前指令+4   |   当前指令+2   |
|------------|---------------------|--------------|----------------|
|  预取指中止|  SUBS PC,R14_abt,#4 | 当前指令+4   |   当前指令+4   |
|------------|---------------------|--------------|----------------|
|  FIQ       |  SUBS PC,R14_fiq,#4 | 当前指令+4   |   当前指令+4   |
|------------|---------------------|--------------|----------------|
|  IRQ       |  SUBS PC,R14_irq,#4 | 当前指令+4   |   当前指令+4   |
|------------|---------------------|--------------|----------------|
|  数据中止  |  SUBS PC,R14_abt,#8 | 当前指令+8   |   当前指令+8   |
 ------------------------------------------------------------------


从上面这个表可以看出:
BL           返回后执行BL的下一条指令
SWI          返回后执行SWI的下一条指令
未定义指令   返回后执行未定义指令的下一条指令
预取指中止   返回后执行重新执行一遍预取指中止指令
FIQ          返回后执行被FIQ中断的指令
IRQ          返回后执行被IRQ中断的指令
数据中止     返回后执行重新执行一遍数据中止指令

使用特权

评论回复
5
ahyjj| | 2007-11-8 14:36 | 只看该作者

到底该是怎样?

以下是一个网友对arm异常出/入口的理解:
——————————————————————————————————
                      arm异常返回小议
 初学ARM,可能会被异常返回这个东西搞得头大。一会儿直接MOV PC,LR,一会儿LR-4,甚至有时要LR-8。为什么要-4,又或者为什么要-8?

    当然了,如果你只是简单地想编个程序,基本上照抄ARM公司给的范例就可以了。但是凡事总想知道个所以然来,所有在这里简单地想议一议ARM的异常返回,到底为什么要-4,为什么要-8。

    想了解这些,至少要了解以下几个方面的问题:一、异常的种类。什么行为导致了异常,这一点非常重要,它关系到产生异常的指令是否要重新执行一遍,如果要重新执行,LR就要多减一个4(4字节,一个指令增量),这样PC才能指向你要重新执行的指令。二、异常发生时,PC值有没有更新?这一点也非常重要,如果PC值没有更新,LR就要少减一个4,如果PC值更新了,就要多减一个4。为了弄懂这一点,需要我们去了解ARM指令执行过程,到底是什么时候更新的PC值。刚才好像想到还有一点,只是刚接了一个电话,忘了。汗!

    当然,在了解上面所有问题之前,首先需要清楚的就是ARM7的“取指->译码->执行”三级流水线。另外,需要明白的还有一个就是在异常发生时,处理器已经做过了SUBS LR,PC,#4。也就是说,LR已经进行了一次减4。

    举一个最简单的例子:IRQ和FIQ(为啥举这个例子捏,因为,介个.....,别的异常我还没搞清楚哈!):

首先是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 PC,I1。I1不合法啊,那就应该是I1=I2-4=LR-4。于是返回指令就是SUBS PC,LR,#4。

    以上就是俺一点心得,很小,但是得来的很不容易啊!现在ARM的资料很多,中用的很少,大家基本都是抄来抄去。翻了无数的参考书,查了很多论文,终于算是基本知道中断返回应该怎么做了。自己看书,周围基本没有人可以交流,不知道理解是不是对的,大家指正。另外,对其它几个异常产生的原因还不是非常了解,在此不敢妄自揣度,向大家请教! 
——————————————————————————————————
按照这位网友的理解:

BL           返回后执行BL的下一条指令
SWI          返回后执行SWI的下一条指令
未定义指令   返回后执行未定义指令的下一条指令

这和楼主的观点一样,其原因是“在异常发生时,PC值没有更新”

FIQ          返回后执行被FIQ中断的下一条指令
IRQ          返回后执行被IRQ中断的下一条指令

这和楼住的观点都不同了,之所以返回时要执行”SUBS PC,R14_mode,#4" 
这条指令是因为异常发生后PC的值已经改变,当前被打断的指令已经执行完毕
PC已经预取了当前指令+ 12的那条指令,所以异常返回时要R14要多减一个4

对于异常的出/入口问题一直是困扰初学ARM者一道难题,即时是周工推荐的好书《ARM嵌入式系统基础教程》也不够详细。我想有必要请周工专门为大家详细说明一下
1、异常发生时流水线中处于“执行”状态的指令是否可以得到充分执行完毕
2、异常发生时PC是否更新?


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

34

帖子

0

粉丝