You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC生成RISC-V的jal指令出现异常?请求排查操作问题

问题分析与解决

操作错误点

  1. 编译阶段误用链接器参数
    你使用了-c参数编译,这个参数仅负责生成目标文件(.o),不会执行链接步骤,但同时添加的链接器参数-Wl,-Ttext=0x0在-c阶段完全无效——因为链接器根本没有参与该阶段的工作。

  2. 未遵循RISC-V JAL指令的寻址规则
    RISC-V的jal指令采用PC相对寻址,而非直接指定绝对地址:

    • 指令中的立即数是相对于当前指令下一条地址(即PC = 当前指令地址 + 4)的偏移,且偏移以**字(4字节)**为单位,实际字节偏移为立即数左移1位。
    • 你直接写jal a0, 42时,汇编器在未链接的状态下(-c阶段)无法确定当前指令的加载地址,也就无法计算出正确的PC相对偏移,最终只能生成偏移为0的指令,即反汇编显示的jal a0,0x0。

正确操作步骤

方式一:一步完成编译链接

去掉-c参数,让gcc直接完成编译+链接流程,同时传递链接器参数指定代码段起始地址:

riscv64-linux-gnu-gcc -Wl,-Ttext=0x0 -nostdlib -mno-relax -o test_jal test_jal.s

方式二:分阶段编译+链接

  1. 编译生成目标文件:
riscv64-linux-gnu-gcc -c -mno-relax -o test_jal.o test_jal.s
  1. 链接时指定代码段起始地址:
riscv64-linux-gnu-ld -Ttext=0x0 -nostdlib -mno-relax -o test_jal test_jal.o

生成原始二进制文件

完成链接后,再用objcopy生成二进制文件:

riscv64-linux-gnu-objcopy -O binary test_jal test_jal.bin

验证结果

如果你的需求是跳转到绝对地址0x42,链接完成后反汇编应该会显示正确的jal a0,0x42,对应的十六进制代码也会是计算后的正确值(当前指令位于0x0时,PC为0x4,偏移字节为0x42 - 0x4 = 0x3E,字偏移为0x3E >> 1 = 0x1F,指令二进制应为0x6F1F0000)。

内容的提问来源于stack exchange,提问作者Euphonious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:40:36