RISC-V中JAL和JALR指令的偏移地址

时间:2019-12-03 05:21:31

标签: riscv

在RISC-V规范中,JAL和JALR指令的立即数被转换为跳转偏移量,如下所示:

  1. 符号将给定的立即数扩展到XLEN位。

  2. 将LSB设置为零。

对此我有几个问题。

问题1

对于JAL,这给出了一个范围:

000000000000 to 111111111110

即4KiB。

在这里,如果LSB始终必须为零,为什么不立即数被视为地址的强制零LSB之前的12位,因此将地址范围扩大到:

[000000000000]0 to [111111111111]0      

[]代表给定的立即偏移量,并且内部给定的立即偏移量的末尾添加了零。也就是说,

  1. 向左移一点地址。

  2. 符号将结果扩展到XLEN位。

问题2

正偏移量和负偏移量如何区分?给定偏移量的MSB是否被使用?

1 个答案:

答案 0 :(得分:1)

JAL具有20位偏移量和一个寄存器作为操作数。

其操作为pc := pc + sxt ( imm20 << 1 )

从公式中可以看到,该分支是pc相对的。立即数可以从JAL本身达到+/- 1 MB。立即数偏移一位,真实的LSB始终为零,因此不进行编码。

因为RISC V支持16位(两个字节)的倍数的指令,所以我们不能假定next-to-LSB也为零,就像MIPS(具有32位指令)一样。

JAL中的寄存器操作数除执行分支外,还可用于捕获返回地址。

JAL的功能是使用其20位范围适度地执行相对于pc的分支或调用。 (与RISC V条件分支指令的+/- 4 KB范围只有12位相反。)


JALR具有12位偏移和两个寄存器作为操作数。

其操作为pc := ( rs1 + sxt ( imm12 ) ) & -2

从公式中可以看出,相对于rs1中的值,分支是间接寄存器。

JALJALR一样,也可以捕获寄信人地址。

JALR用于从函数返回(汇编中也称为RET。以这种形式,$ ra用作源寄存器,并且不捕获返回地址)。偏移量使用零(即不需要偏移量)。

JALR也用于执行间接函数调用:通过函数指针,虚拟方法分派等进行的调用。这些偏移量也使用零。

JALR也可以与AUIPC依次使用。


AUIPC具有20位偏移量和一个寄存器作为操作数。

其操作为rd := pc + ( imm20 << 12 )

它计算pc相对即时数的上部(同时还提供pc相对非即时数的下部)。

JALR结合使用,可以完成32位相对于PC的分支或调用。

AUIPC r5, labelFarAway      # AUIPC encodes upper 20 bits of label's distance from pc
JALR r5, $ra, labelFarAway  # JALR encodes the lower 12 bits of same