MARS模拟器具有PC相对寻址是指字节数而不是单词吗?



我目前正在阅读David Patterson和John Hennesy的书,标题为"计算机组织与设计 - 第4版"。在书中,书中说:

由于所有MIPS

指令的长度均为4个字节,因此MIPS通过让PC相对寻址引用 单词到下一条指令,而不是字节数。

当我读到这句话时,我就去了MARS模拟器,看看它在实践中。令我惊讶的是,我观察到$pc寄存器不遵循该规则,并且始终存储字节内存地址。

在执行位于指令地址中的以下指令之前,$pc寄存器不应该是这样的吗?

Instruction Address |    $pc Content
|
0x00400000      |     0x00100000
0x00400004      |     0x00100001
0x00400008      |     0x00100002
....          |         ....

另一种看待这个问题的方式:PC 的低 2 位固定在0.

根据您的建议,高 2 位将固定为0.jr $ra或其他跳转到寄存器指令也必须左移寄存器,而不是简单地设置$pc = function-pointer

(否则,差异在体系结构上是可见的,并且必须将代码作为数据访问,反之亦然,才能从数据地址转换为同一单词的代码地址。


正如Jester指出的那样,$pc是指向指令字的普通指针,就像MIPS习惯于处理一样。 MIPS使用字节可寻址存储器,但字加载必须对齐(直到MIPS32r6)。 因此,$pc增量为 4,而不是每次使用时都按 4缩放

实际设计唯一需要的缩放是分支(I型)和跳跃(J型)的即时缩放。 请参阅如何计算跳转目标地址和分支目标地址?了解其工作原理。 这只是您将即时位连接到加法器的位置问题,使较低的位为零。 它只发生在这些指令的解码中;其他一切都仅适用于普通字节地址。

...通过让 PC 相对寻址引用下一条指令的字数而不是字节数来延长分支的距离。

这句话的意思只有

存储在地址X的指令0x1000nnnn(b nnnn)将跳转到地址X+4+4*nnnn的指令,而不是地址X+4+nnnn的指令。

这句话没有提到PC寄存器及其价值本身。

我观察到$pc寄存器不遵循该规则,并且始终存储字节内存地址。

在执行位于指令地址中的以下指令之前,$pc寄存器不应该是这样的吗?

这里的问题是:$pc寄存器到底是什么?

在某些CPU(如ARM)上,有些指令将以MIPS汇编语言编写为addu $t0,$t0,$pc。谈论这样的CPU,很容易回答这个问题:

$pc寄存器的值是在执行指令addu $t0,$t0,$pc时将添加到$t0的值。

在真正的MIPS CPU(不是MIPS仿真器)上,PC寄存器是某种存储器(30位锁存器),可以容纳30位信息。

但是,当谈论存储在某些内存中的信息时,我们必须定义如何解释信息:

10000111位可以解释为 135(无符号)、87(BCD)、-121(二的补码)、-120(一补码)、-7(符号和绝对)、SOME_ENUM_CONSTANT(枚举)、-0.09、0.7、1.35(各种浮点和定点变体)......

PC寄存器中0000...011100的位指向地址0x70处的指令,这是明确定义的。但是,没有定义此值是否必须写为PC=0x1CPC=0x70

因此,一些MIPS仿真器可能会显示$pc=0x400000,而另一个可能会显示PC寄存器中相同值的$pc=0x100000

但是,我认为(几乎)所有MIPS模拟器都会显示$pc=0x400000,因为用户对指令指向的地址感兴趣。

最新更新