mips - "extend immediate to 32 bits"在MIPS中是什么意思?

标签 mips cpu-architecture machine-code sign-extension immediate-operand

我正在阅读有关 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/

相关文章:

c - 机器指令中的LEAL和MOVL

.net - native 代码和托管代码之间的区别?

assembly - andi和ori在这个程序中做了什么?

cuda - 内存合并与矢量化内存访问

algorithm - 在 MIPS 中查找字数组中的重复整数

Python CPU 和操作系统

cpu-architecture - 什么是影子寄存器文件以及什么是窄寄存器文件?

assembly - 为什么 ia32/x64 操作码映射文档 0x66 和 0xF2 作为操作码 0x0F38F1 (CRC32) 的双重强制前缀?

assembly - 为什么我们使用字节寻址而不是字寻址?

assembly - 编译 MIPS 程序集源时出现初学者错误