我正在阅读 MIPS 数据路径中的指令解码 (ID) 阶段,我得到以下引用:“一旦知道操作数,就读取实际数据(从寄存器)或将数据扩展到 32 位(立即数) 。”
有人可以解释“将数据扩展到 32 位(立即数)”部分是什么意思吗?我知道寄存器都包含 32 位,而且我知道立即数是什么。我只是不明白为什么需要将立即数从 26 位扩展到 32 位。
谢谢!
我正在阅读 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^15-1
ori
//布尔立即数是零扩展的(通过将所有高位设置为零)这允许对无符号/2的补码andi
进行编码。(0x00000000 到 0x0000FFFF)xori
0 .. 2^16-1
有关其他说明,请参阅此指令集参考,其中分解了显示 0 16 ||的每条指令 [I 15..0 ] 用于零扩展或 [I 15 ] 16 || [I 15..0 ] 用于符号扩展。
这使得使用 16 位立即数作为 32 位二进制运算的输入成为可能,只有 2 个等宽输入才有意义。(在一个简单的经典 MIPS 流水线中,解码阶段从寄存器和/或立即数中获取操作数。寄存器输入总是 32 位的,因此 ALU 连接到 32 位输入。将立即数扩展到 32 位意味着CPU 的其余部分不必关心数据来自立即数还是寄存器。)
也符号扩展:
lw
/sw
和其他加载/存储指令使用的 reg+imm16 寻址模式中的偏移量PC += imm16<<2
)也许其他人,请查看手册以获取我未提及的说明,以查看它们是符号扩展还是零扩展。
您可能想知道“为什么addiu
即使它是无符号的,符号扩展它的立即数?”
请记住,没有subiu
,只有addiu
一个否定的立即数。能够在范围内添加或减去数字-2^15 .. +2^15-1
比仅能够添加更有用0 .. 2^16-1
。
通常你不想在有符号溢出时引发异常,所以通常编译器使用addu
/addiu
甚至在有符号整数上。 addu
名字不好:它不是“用于无符号整数”,它只是 / 的允许包装/永不出错的add
版本addi
。如果您想到 C 语言,这是有道理的,其中有符号溢出是未定义的行为(因此add
如果编译器想要以这种方式实现它,则可以在这种情况下使用并引发异常),但无符号整数具有明确定义的溢出行为:基地2环绕。
在 32 位 CPU 上,您执行的大多数操作(如加、减、取消引用指针)都是使用 32 位数字完成的。当您有一个位数较少的数字时,您需要以某种方式决定当您想在其中一个操作中使用该数字时其他位将是什么。决定这些新的高位是什么的行为称为“扩展”。
假设你只是在做一个标准的零扩展或符号扩展,扩展是非常便宜的。然而,它确实需要一些电路,因此在 MIPS 数据路径的描述中提及它是有道理的。