【发布时间】:2011-11-19 16:33:39
【问题描述】:
我正在学习 MIPS 32 位。我想问一下,为什么我们在存储字的情况下,在将 16 位偏移(在单周期数据路径中)发送到 ALU 之前要对它进行签名扩展?
【问题讨论】:
标签: mips instruction-set mips32
我正在学习 MIPS 32 位。我想问一下,为什么我们在存储字的情况下,在将 16 位偏移(在单周期数据路径中)发送到 ALU 之前要对它进行签名扩展?
【问题讨论】:
标签: mips instruction-set mips32
听起来 16 位偏移量是一个有符号的 2's complement 数字,即它可以是正数或负数。
转换为32位时,需要将最高位复制到高16位,以保留符号信息。
【讨论】:
我现在不确定它是否对你有帮助,但我还是会发布它。
让我们从一个非常笼统的意义上来考虑 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 位到“左”的原因,因为,将任何二进制值左移n 位导致将该值乘以 2^n。在我们的例子中 2^2 = 4
所以分支指令的实际目标地址是PC+4+4*Offset。
希望这会有所帮助。
【讨论】:
据我所知,在加载或存储指令中,偏移值被添加到临时寄存器中的值中,作为 temp。寄存器是32位的,不能进行16位和32位的加法运算,值是符号扩展的。
【讨论】:
我认为您在这里的概念有些错误。
您认为进入 ALU 的 5 位实际上进入寄存器内存以选择 32[2^5] 个寄存器中的一个。
每个寄存器本身都是 32 位的。因此,要将偏移量添加到寄存器值,您需要将其符号扩展为 32 位。
ALU 操作总是在 MIPS 的单周期数据路径中的两个相同大小的寄存器之间进行。
【讨论】:
在 32 位机器的硬件中,大多数 ALU 采用 32 位输入,所有寄存器都是 32 位寄存器。
要处理您的数据,它必须是 32 位宽,这就是我们进行 SIGN 扩展的原因,但另一种方法是零扩展,但在处理立即数和偏移量时使用 SIGN 扩展来保留签入 2 的补码。
【讨论】:
标志扩展发生,例如对于 M68xxx 机器,仅在加载地址寄存器的情况下。在数据寄存器的情况下不是这样。
例如
movea.w addr,a0
move addr,d0
addr:
dc.w $FFFF
导致数据寄存器加载到 $0000FFFF,如果 但是地址寄存器加载到 $FFFFFFFF。
为了理解这一点,构建带符号负数的两个补码 演示文稿,$FFFF,将数字扩展到 32 位并重做两个- 补码,找到相应的 32 位表示。
干杯和亲切的问候, 斯蒂芬·S.
【讨论】: