RISC-V使用LUI / ADDI在寄存器中生成-1 / 0xFFFFFFFF吗?

时间:2019-07-27 18:06:30

标签: assembly riscv

我正在学习如何为RISC-V处理器编写代码。我想将0xFFFFFFFF的值存储到内存/寄存器中。

我可以通过在addi之前添加lui来扩展lui t0, 0xFFFFF addi t0, t0, 0x7FF 指令的12个立即数, 像这样的东西:

0xFFFFF7FF

但是结果最终将类似于import Header from '../components/Header';

那么,我该如何生成该值?

2 个答案:

答案 0 :(得分:2)

询问C编译器:

unsigned foo(){return 0xFFFFFFFF;}

使用Clang -O3编译为RISC-V (on Godbolt)的asm:

foo():
    addi    a0, zero, -1
    ret

(gcc仅使用li a0, -1伪指令,并将细节留给汇编器。通常,您应该这样做,除非您想考虑选择可以更高效地生成的常量。)


RISC-V addi将其立即操作数符号扩展为32(或64)位,因此,如果要在第12位中添加一位,则需要在您对高位的选择。

在这种情况下,高位的正确起始值为0,因此您可以完全优化lui

RISC-V使用2的补码有符号整数,因此,符号扩展仅表示加宽时将符号位复制到所有更高的位置。

答案 1 :(得分:1)

让我们首先分析您的代码问题在哪里:

lui t0, 0xFFFFF
addi t0, t0, 0x7FF
  • lui指令将20位立即数t0左移12位后得到的值加载到0xFFFFF中。因此,t0产生0xFFFFF000
  • addi sign extends 12位立即数0x7FF,并将其添加到寄存器t0中。由于立即数的最高有效位(即符号位)为零,因此其符号扩展的32位值为0x000007FF。然后将此值添加到先前为t0的{​​{1}}中。因此,0xFFFFF000的最终值为t0

正如this answer中已经解释的那样,您可以利用符号扩展的工作方式来优化0xFFFFF7FF指令:符号扩展会传播符号位(最高位)。

12位立即数lui由所有0xFFF组成,包括最高有效位(即符号位)。因此,其32位符号扩展名是1,它已经对应于您想要的值:

0xFFFFFFFF

如果您一直坚持使用addi t0, zero, 0xFFF lui这两个指令,只需将所有addi加载到0的高位:

t0