存储在 MIPS PC 中的值
Value stored in the MIPS PC
我知道所有 MIPS 指令都是 4 个字节长。由于 PC 包含下一条指令的地址,因此 PC 的前 2 位始终为 0。
在PC中包含这2位,貌似缩小了PC的范围,那么PC为什么要这样实现呢?
我是计算机体系结构的新手,所以请指出我对这个概念的理解上的任何差距。
mips [32 位] 架构只能有 32 位的地址。这意味着一个 4GB 地址 space。因此,一台 32 位宽并使用 byte 寻址的 PC 可以在 space.
中寻址 anything
你想的是,而不是包含 byte 地址的 PC,其中最右边的两位总是零,因为指令必须是 4 byte/word对齐,并且似乎是 "wasted",为什么不让 PC 包含一个 字 地址,该地址将左移两位以产生 34 位地址。这将跨越 16GB。
但是,这将超出 mips 内存系统能够寻址的范围。因此,这样做没有任何好处,因为不能使用更宽的结果地址,因为它超出了体系结构的可寻址能力。因此,对于字节地址,没有什么是真正浪费的。
整个 32 bit/4GB 地址 space 的所有地址计算都适合 32 位宽的寄存器。在 64 位架构上,寄存器是 64 位的,可以跨越更大的范围。
所以,无论如何,PC
本身拥有 byte 个地址,但是 ...
... 您的想法可以被使用并且被使用的地方是在分支指令中编码目标偏移量时。它们的形式是:
00000000 beqz $t0,XXXX
00000004 nop
mips 与其他架构有些不同:
XXXX
是 signed 16 位 word 相对于 PC + 4
的偏移量。在这种情况下,PC + 4
是 0x00000004。我们将 XXXX
和 sign 扩展为 32 位。然后,我们将它左移两位。然后,我们将其与PC + 4
相加,得到分支的最终目标地址。 "we",我指的是 mips 分支指令硬件。
考虑相反的情况,我们有以下程序片段:
00000000 nop
00000004: nop
00000008 loop: nop
0000000C nop
00000010 nop
00000014 beqz $t0,loop
00000018 nop
为了在分支指令中得到 XXXX
的正确值,汇编程序获取标签 loop:
的地址并从中减去 PC + 4
以产生相对字节偏移量.这里,loop
的地址是0x00000008,PC + 4
的地址是0x00000018,所以我们有0x08 - 0x18
,也就是-0x10
或0xFFFFFFF0
。这是一个 byte 偏移量,因此我们将其右移两位以产生 word 偏移量:0xFFFFFFFC
。我们将其低 16 位用于 XXXX
,因此我们有 FFFC
因为分支指令使用 word 偏移量而不是 byte 偏移量,所以它们不会 "waste" 两个 "must be zero" 位。他们利用这一点将分支指令 byte 偏移量的范围从 -32768 to 32767
扩展到 -131072 to 131068
.
我知道所有 MIPS 指令都是 4 个字节长。由于 PC 包含下一条指令的地址,因此 PC 的前 2 位始终为 0。 在PC中包含这2位,貌似缩小了PC的范围,那么PC为什么要这样实现呢?
我是计算机体系结构的新手,所以请指出我对这个概念的理解上的任何差距。
mips [32 位] 架构只能有 32 位的地址。这意味着一个 4GB 地址 space。因此,一台 32 位宽并使用 byte 寻址的 PC 可以在 space.
中寻址 anything你想的是,而不是包含 byte 地址的 PC,其中最右边的两位总是零,因为指令必须是 4 byte/word对齐,并且似乎是 "wasted",为什么不让 PC 包含一个 字 地址,该地址将左移两位以产生 34 位地址。这将跨越 16GB。
但是,这将超出 mips 内存系统能够寻址的范围。因此,这样做没有任何好处,因为不能使用更宽的结果地址,因为它超出了体系结构的可寻址能力。因此,对于字节地址,没有什么是真正浪费的。
整个 32 bit/4GB 地址 space 的所有地址计算都适合 32 位宽的寄存器。在 64 位架构上,寄存器是 64 位的,可以跨越更大的范围。
所以,无论如何,PC
本身拥有 byte 个地址,但是 ...
... 您的想法可以被使用并且被使用的地方是在分支指令中编码目标偏移量时。它们的形式是:
00000000 beqz $t0,XXXX
00000004 nop
mips 与其他架构有些不同:
XXXX
是 signed 16 位 word 相对于 PC + 4
的偏移量。在这种情况下,PC + 4
是 0x00000004。我们将 XXXX
和 sign 扩展为 32 位。然后,我们将它左移两位。然后,我们将其与PC + 4
相加,得到分支的最终目标地址。 "we",我指的是 mips 分支指令硬件。
考虑相反的情况,我们有以下程序片段:
00000000 nop
00000004: nop
00000008 loop: nop
0000000C nop
00000010 nop
00000014 beqz $t0,loop
00000018 nop
为了在分支指令中得到 XXXX
的正确值,汇编程序获取标签 loop:
的地址并从中减去 PC + 4
以产生相对字节偏移量.这里,loop
的地址是0x00000008,PC + 4
的地址是0x00000018,所以我们有0x08 - 0x18
,也就是-0x10
或0xFFFFFFF0
。这是一个 byte 偏移量,因此我们将其右移两位以产生 word 偏移量:0xFFFFFFFC
。我们将其低 16 位用于 XXXX
,因此我们有 FFFC
因为分支指令使用 word 偏移量而不是 byte 偏移量,所以它们不会 "waste" 两个 "must be zero" 位。他们利用这一点将分支指令 byte 偏移量的范围从 -32768 to 32767
扩展到 -131072 to 131068
.