设置小于立即无符号:可表示整数的范围 - MIPS

Set on Less Than Immediate Unsigned: Range of representable integers - MIPS

我目前正在写一篇关于机器语言和 MIPS 的研讨会论文,在学习 Set on Less Than Immediate Unsigned Instruction 时,我发现了一些我不明白的奇怪之处。

MIPS v5 Documentation(第 277 页)指出 16 位立即数在与寄存器 rs 的内容进行比较之前进行了符号扩展,但被视为无符号。这意味着,他们还在文档中声明,您可以表示 32 位无符号整数的下半部分和无符号整数的上半部分,两者之间有很大的差距。这是有道理的,因为您的立即数前面有 16 个零或 16 个。

现在我不太明白他们提供的数字作为示例:他们说可表示的无符号整数的下半部分和上半部分各为 32,767,这是 15 位可表示的最大数字。但是它们不应该每个都大 65,535(最大的 16 位可表示数),因为整数是无符号的,因此 MSB 不用作符号位吗?

两个范围都是 32768,而不是 7。全​​套 2^16 (65536) 个可编码的 16 位立即数被分成两部分,高位设置高位,低位清除。

(官方 MIPS 文档当然是正确的,说 可表示的值在无符号范围的最小 [0, 32767] 或最大 [max_unsigned-32767, max_unsigned] 端。 这些是包含范围,因此它们每个都包含 32768 个数字。计数很重要,请注意 off-by-1 错误。)


可编码的值范围是

  • 0x00000000 .. 0x00007FFF(符号扩展产生零):最小无符号数
  • 不可编码;你需要多条指令
  • 0xffff8000 .. 0xffffFFFF(符号扩展产生一个):最高无符号数

(我使用小写 f 作为符号扩展的结果,大写 F 用于直接编码的部分。)


对于像 slti(不是 u)这样将值视为有符号的其他指令,这些相同的十六进制值仍然是您可以编码的位模式,但您将它们解释为 -32768(0xffff8000) .. 32767 (0x00007FFF).

有趣的事实:像 ori 这样的 MIPS 按位布尔指令对它们的立即数进行零扩展,这样你就可以用一个 ori $dst, $zero, imm16 指令在一个寄存器中构造 0 .. 65535 (0x00000000 .. 0x0000FFFF)。相比之下,RISC-V 总是对立即数进行符号扩展。