我正在阅读有关 MIPS 数据路径中的指令解码 (ID) 阶段的内容,并得到以下引用:“一旦知道操作数,就可以(从寄存器中)读取实际数据或将数据扩展到 32 位(立即数)。”
有人可以解释一下“将数据扩展到 32 位(立即数)”部分的含义吗?我知道寄存器都包含 32 位,并且我知道立即数是什么。我只是不明白为什么需要将立即数从 26 位扩展到 32 位。
谢谢!
最佳答案
26 位立即数仅出现在跳转指令中,并且不会通过符号或零扩展为 32 位,因为它们不是要进行加/减的位移。
具有 16 位立即数的 I 类型指令是不同的。
-
addi
/addiu
立即数经过符号扩展(通过将立即数的顶部/符号位复制到所有较高位)。 https://en.wikipedia.org/wiki/Two%27s_complement#Sign_extension
这允许-2^15
中的 2 的补数..+2^15-1
进行编码。
(0xFFFF8000 至 0x00007FFF) -
ori
/andi
/xori
bool 立即数为零扩展(通过将所有高位设置为零)
这允许来自0 .. 2^16-1
的无符号/2的补数进行编码。
(0x00000000 至 0x0000FFFF)
有关其他说明,请参阅此 instruction-set reference它分解了每条指令,显示 016 || [I15..0] 零扩展或 [I15]16 || [I15..0] 用于符号扩展。
这使得可以使用 16 位立即数作为 32 位二进制运算的输入,该运算仅对 2 个等宽输入有意义。 (在简单的经典 MIPS 管道中,解码阶段从寄存器和/或立即数获取操作数。寄存器输入始终为 32 位,因此 ALU 已连接用于 32 位输入。将立即数扩展到 32 位意味着CPU 的其余部分不必关心数据是来自立即数还是寄存器。)
也进行符号扩展:
-
lw
使用的 reg+imm16 寻址模式中的偏移量/sw
以及其他加载/存储指令 - 相对分支 (
PC += imm16<<2
)
也许其他人,请检查手册中我没有提到的说明,看看它们是否进行符号扩展或零扩展。
您可能想知道“为什么 addiu
会对其立即数进行符号扩展,即使它是无符号的?”
请记住,没有 subiu
,仅 addiu
带有负立即数。能够对 -2^15 .. +2^15-1
范围内的数字进行加减运算比只能添加 0 .. 2^16-1
更有用.
通常您不想在有符号溢出时引发异常,因此编译器通常使用 addu
/addiu
即使是有符号整数。 addu
名字很糟糕:它不是“用于无符号整数”,它只是 add
的允许包装/永不出错的版本/addi
。如果你想到 C,这是有道理的,其中有符号溢出是未定义的行为(因此可以使用 add
并在这种情况下引发异常,如果编译器想要以这种方式实现它),但无符号整数有明确定义溢出行为:基数 2 环绕。
关于mips - "extend immediate to 32 bits"在MIPS中是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55290060/