关于QEMU Virt机器中%pcrel_hi与%pcrel_lo的执行结果疑问
关于RISC-V auipc指令与%pcrel_hi计算的疑问解答
核心问题拆解
你对auipc指令的执行逻辑存在误解,导致计算结果和GDB实际输出不符,以下是具体分析:
- auipc指令的正确执行逻辑
auipc rd, imm的本质是将立即数左移12位后,加上当前指令的PC地址,赋值给目标寄存器,即:
rd = PC + (imm << 12)
在你的场景中,auipc指令位于地址0x1000,所以PC的值就是0x1000。
- %pcrel_hi(fw_dyn)的计算与实际执行结果
你计算%pcrel_hi(fw_dyn)=(0x1028-0x1000)>>12=0x0是正确的,但你忽略了auipc需要加PC的步骤。代入指令逻辑:
t0 = 0x1000 + (0x0 << 12) = 0x1000
这和GDB显示的t0=0x1000完全一致。
- 第二条指令的验证逻辑
第二条指令addi a2, t0, %pcrel_lo(fw_dyn)(你描述中的1b应为笔误,实际是指向fw_dyn的低12位偏移)中,%pcrel_lo(fw_dyn)的值是0x28(即0x1028-0x1000的低12位),执行后:
a2 = 0x1000 + 0x28 = 0x1028
这也符合你观察到的结果。
- 补充:%pcrel_hi的完整计算规则
RISC-V汇编器中%pcrel_hi(symbol)的完整计算式是:
((symbol - PC) + 0x800) >> 12
这个公式是为了配合%pcrel_lo处理低12位的符号扩展问题,但在你的场景中,symbol-PC=0x28,加上0x800后为0x828,右移12位仍为0x0,所以imm值确实是0x0,和你的计算一致。
内容的提问来源于stack exchange,提问作者Ericccccccc
相关产品推荐
相关产品推荐

