问一个有关流水线和Expection的问题:为什么Data abort的handler需要将lr减8再送回pc。虽然看了一些书和pdf,但还是有些疑问,我先说说我的理解,如果有误请高手指正,谢谢。
我用的是44b0x的芯片,应该是ARM7TDMI的核。我查了一下ARM7的流水线是3级:取指、译码和执行。其中,译码分为:寄存器译码和寄存器选择两步,执行分为:寄存器读取、移位、运算和寄存器写入四步。这就是为什么在ARM(32bit)模式下,PC指向正处于执行阶段的指令(PC-8)之后两条指令的地方(PC指向的地方在取指,PC-4的地方在译码)。
软件中断和指令未定义是在指令的执行阶段引起例外的,所以该语句的位置是PC-8,送入LR的值是PC-4(下一条指令即正处于译码阶段的指令),因此返回时只需将LR直接送给PC(此时流水线上应该只有这一个有效的指令,但似乎这条指令会重新经历取指过程,不知道是不是这样)。
中断和快速中断的检测是在每执行完一条指令之后(即流水线移动一格之后)进行的,所以PC-8已经指向原本下一条要执行的语句了,因此要将LR中的原PC-4再减去4,这样中断返回之后PC的值就是原来中断前的PC-8,不过这样又要重新取指和译码了。
预取指中止(就是Prefetch abort,不知道翻成什么)是在取指阶段识别的,但是在执行阶段才引发的(PC-8,流水线仍正常执行,该干嘛还干嘛)。由于已经作了出错标记,所以应直接转入Exception,但由于该指令需要再次执行所以返回后PC的值应该是原来的PC-8,所以在调用Exception时,将LR中的原PC-4再减去4。
下面就是问题了,数据中止(Data abort)也应该是在执行时才引发的,似乎也应该是PC-8,但是有关资料上称,此时PC已经更新也就是说当前中止的指令应该是PC-12,这似乎解释了为了重新执行该指令(原PC-12)需要将LR中的原PC-4再减去8的原因。
其中有个疑问:PC究竟是什么时候更新的呢?如果按照上边的理解,应该是在引发Exception之前,是不是因为在指令执行时都是操作寄存器,而Data abort是在操作memory时引起的,晚于“指令”的执行?那对内存的操作又是什么时候呢?流水线之外吗?
在下刚碰ARM不到两个星期,还不太懂,望各路高手指点指点,谢谢。
[em04]