auipc

auipc

RISC-V 汇编 参考

lyszt.net 更详细地介绍了 auipc 和其他 RISC-V 指令。

编码格式

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

描述

auipc 代表 add upper immediate to PC。它的工作方式类似 lui,取一个 20 位常量作为值的高位部分。auipc 将该值加到程序计数器上,程序计数器保存着当前正在运行的指令的地址(参见 beq 页面)。结果是一个相对于该指令在内存中所处位置来度量的地址。

相对地址解决了一个实际问题。程序并不总是知道它会被加载到内存中的哪个位置。用固定的绝对地址引用其数据的代码在被加载到别处时就会失败。而相对于当前指令计算地址的代码无论被放在哪里都能工作。这一性质称为位置无关性。

auipc 提供这种地址的粗略部分,随后的一条指令加上精细的 12 位余数。加载标签地址的 la 指令就是由这一对构成的,对远处函数的调用也是如此。

RISC-V 手册说,将 auipc 的常量设为 0 即可获得当前的 pc。auipc 后跟一条 jalr 可以将控制转移到任意 32 位 pc 相对地址,而 auipc 后跟一条带 12 位偏移的加载或存储可以访问任意 32 位 pc 相对数据地址。

la 和 call 的存在是为了让你不必手写 auipc,它经常出现在模拟器的跟踪记录和反汇编代码中。auipc 后跟一条带小偏移的指令、共同构成一个地址,是一个值得识别的好模式。

示例

auipc t0, 1      # t0 = pc + 0x1000