MIPS 上的 LUI/ORI 如何创建 32 位常量值?

How does LUI/ORI on MIPS work to create a 32-bit constant value?

我有这个风险代码:

lui S0, 0x1234
ori S1, S0, 0x5678
add S2, S1, S1

然后问题问我,“寄存器 S2 保存什么?” 问题解释说 lui 我引用:

"将立即数imm的低半字载入寄存器rt的高半字,寄存器低位设置为0"

我不知道如何 'compile this program' 以及 0x1234 是什么意思?


注:本题原为titled/tagged,但代码只能assembleMIPS,接受的答案也只对MIPS正确。所以让我们把它变成一个 MIPS 问题。

MIPS 将 16 位立即数用于 lui 和所有其他立即数指令,并零扩展按位布尔立即数 (ori/andi/xori)。其他 MIPS 指令会对其立即数进行符号扩展,就像 RISC-V 对所有内容所做的那样。

RISC-Vlui取20位立即数,而其他指令只取12位符号扩展立即数,所以luiand/oraddi can still materialize any 32-bit constant in 1 or 2 RISC-V instructions,像 MIPS 和所有(?)其他 32 位 RISC ISA。

一次看一个说明。首先 load-upper-immediate,将立即数 (0x1234) 和 "load" 放入 S0 寄存器的上半部分并清零下半部分:

lui S0, 0x1234 

S0 = 0x12340000

接下来 or-immediate,我们将 S0 中的值与值 0x5678 进行或运算:

ori S1, S0, 0x5678

   0x12340000
OR 0x00005678
   ----------
   0x12345678 = S1

最后 add,我们将 S1 中的值与其自身相加,或者等效地,将 S1 中的值乘以 2:

add S2, S1, S1

  0x12345678
+ 0x12345678
  ----------
  0x2468ACF0 = S2

所以S2寄存器中的值为0x2468ACF0。请注意,我假设是 32 位字。立即数就像一个常量,因此 lui 是一条将常量放入寄存器上半部分的指令。与 ori 结合使用,您可以将整个字立即加载到寄存器中。

"LUI places the U-immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros." -- riscv-spec-v2.2

所以, 路易 s0, 0x1234

s0 应该是 0x01234000