8

我正在学习 MIPS 32 位。我想问一下,在存储字的情况下,为什么我们在将 16 位偏移量(在单周期数据路径中)发送到 ALU 之前要对其进行签名?

4

6 回答 6

12

我不确定它现在是否对您有帮助,但无论如何我都会发布它。

让我们从一个非常笼统的意义上考虑,C++ 中的指令数组,即 A[0],A[1],A[2] .....任何两条指令之间的“比喻”距离是 1 UNIT。

让我们把这个类比为 MIPS。在 MIPS 中,比喻每条指令由“1 UNIT”分隔,然而,在 MIPS 中,1 UNIT = 4 Bytes。每条指令都是 4 字节长,这就是为什么当从一条指令移动到另一条指令时,PC 会增加 4,即 PC+4。因此,指令 i 和指令 i+2 之间的差距“象征性地”是 2 但实际上是 2*4=8 即 PC+4+4

回到分支指令中指定的偏移量,偏移量表示距下一条指令(分支之后的指令)的“象征性”距离。因此,为了获得“真实”距离,偏移量将乘以 4。这就是我们被指示将偏移量“符号扩展”2 位到“LEFT”的原因,因为,将任何二进制值左移n 位导致将该值乘以 2^n。在我们的例子中 2^2 = 4

所以分支指令的实际目标地址是PC+4+4*Offset。

希望这可以帮助。

于 2011-10-21T02:11:45.160 回答
8

听起来 16 位偏移量是带符号的 2 的补码,即它可以是正数或负数。

将其转换为 32 位时,需要将最高有效位复制到高 16 位,以保留符号信息。

于 2011-09-18T14:12:43.073 回答
0

在 32 位机器的硬件中,大多数 ALU 采用 32 位输入,所有寄存器都是 32 位寄存器。

要处理您的数据,它必须是 32 位宽,这就是我们进行 SIGN 扩展的原因,但是另一种方法是零扩展,但是在处理立即数和偏移量时使用 SIGN 扩展以保留 2 中的符号补充。

于 2014-03-09T13:43:38.507 回答
0

我认为您在这里的概念有些错误。

您认为进入 ALU 的 5 位实际上进入寄存器内存以选择 32[2^5] 个寄存器中的一个。

每个寄存器本身都是 32 位的。因此,要将偏移量添加到寄存器值,您需要将其符号扩展为 32 位。

ALU 操作总是在 MIPS 的单周期数据路径中的两个相同大小的寄存器之间进行。

于 2014-03-08T15:28:28.447 回答
0

据我所知,在加载或存储指令中,偏移值被添加到临时寄存器中的值中,如 temp。寄存器是 32 位的,不能进行 16 位和 32 位的加法运算,值是符号扩展的。

于 2013-10-27T06:19:58.527 回答
0

符号扩展发生在例如 M68xxx 机器的情况下,仅在加载地址寄存器的情况下。在数据寄存器的情况下不是这样。

有例如

movea.w addr,a0
move    addr,d0
addr:
dc.w $FFFF

在数据寄存器加载的情况下导致 $0000FFFF,在地址寄存器加载的情况下导致 $FFFFFFFF。

为了理解这一点,构建带符号负表示的二补码 $FFFF,将数字扩展到 32 位并重做二补码,找到 32 位的相应表示。

干杯和亲切的问候,斯蒂芬·S。

于 2016-08-12T14:24:00.117 回答