ARM3级流水和5级流水为什么都是PC=PC+8

首先介绍前置知识


arm7采用三级流水

(1)取指(fetch)

取指级的任务是从程序存储器中读取指令。

(2)译码(decode)

译码级完成对指令的分析,并为下一个周期准备数据路径需要的控制信号。

在这一级,指令占用译码逻辑,不占用数据通路。

(3)执行(excute)

完成指令要求的操作,并根据需要将结果写回寄存器。

指令占用数据路径,寄存器堆被读取,操作数在桶行移位器中被移位。

运算器产生运算结果并回写到目的寄存器中,运算器根据指令需求和运输结果更改状态寄存器的条件位。


arm9采用五级流水

(1)取指(fetch)

从存储器中取出指令,并将其放入指令流水线。

(2)译码(decode)

指令被译码,从寄存器堆中读取寄存器操作数。

在寄存器堆中有3个操作数读端口,因此大多数ARM指令能在1个周期内读取其操作数。

(3)执行(execute)

将其中一个操作数移位,并在ALU中产生结果。如果指令是Load或Store指令,则在ALU中计算存储器的地址。

(4)缓冲/数据(buffer/data)

如需要则访问数据存储器,否则ALU只是简单地缓冲一个时钟周期,以使所有的指令具有同样的流水线流程。

(5)回写(write-back)寄存器堆

------------------------------------------------

注意

arm7中执行和取指是隔了一级译码级,那一级不读取数据,当前PC=原PC+8, 正常。

arm9中执行和取指之间的译码级不再老实,译码级已经开始从寄存器堆中读取寄存器操作数,这样的话,

读取到得就是PC+4,不是PC+8,执行级又不会再读一次,那将导致执行级的PC还是=PC+4。

为了保持向下兼容,在ARM9的5级流水线上,取指级增加的PC值被直接送到译码级的寄器,穿过了

两级之间的流水线寄存器,这样译码级得到的PC值就是下一条指令的PC+4,等于当前指令的PC+8,等到

了执行级时,PC寄存器的值=当前指令地址+8

当使用指令STR或STM对R15进行保存时,保存的可能是当前指令地址加8或当前指令地址加12。


到底是哪种方式,取决于芯片的具体设计方式。当然,在同一个芯片中,只能采用一种方式。要么保存

当前指令地址加8,要么保存当前指令地址加12。程序开发人员应尽量避免使用STR或STM指令来对R15进行

操作。当不可避免要使用这种方式时,可以先通过一小段程序来确定所使用的芯片是使用哪种方式实现的。

例如:

SUB R1,PC, #4      ;R1中存放STR指令地址

STR PC,[R0]          ;用STR指令将PC保存到R0指向的地址单元中,

                              ;PC=STR指令地址+偏移量(偏移量为8或者12)。

LDR R0,[R0]           ;读取STR指令地址+偏移量的值

SUB R0,R0,R1       ; STR指令地址+偏移量的值减去STR指令的地址,得到偏移量值(8或者12)。



 


=============================

你可能感兴趣的:(基础知识)