需要RISCV链接器来处理JAL偏移

时间:2016-11-16 03:49:55

标签: gcc riscv

以下RISC-V汇编代码(RV32)用于显示问题。

start:    jal end
end:      jal start

我使用以下简单命令调用汇编程序...

riscv32-unknown-elf-as -m32 example.s -o example.o

要检查生成的代码,我将其反汇编......

riscv32-unknown-eft-objdump -D example.o

其中给出了以下输出......

00000000 <start>:
    0:  004000ef    jal 4 <end>

00000004 <end>
    4:  ffdff0ef    jal 0 <start>

第一个'jal'已经正确地指示它需要向PC添加4以便跳转到下一行,即地址4.(注意:jal指令的立即值的奇数布局意味着实际值指令编码2,然后在CPU乘以2得到4)的实际偏移量。第二个'jal'的偏移量为-2。再次,当CPU乘以2时,我们可以-4作为偏移量。

我实际上想要生成一个不包含ELF信息的原始输出文件,它只由8个字节组成,构成两个指令的8个字节。我直接针对微控制器运行,而且微控制器没有运行操作系统。我希望输出闪存到非易失性RAM,然后在复位时执行。

所以我使用以下链接器命令来生成二进制输出...

riscv32-unknown-elf-ld --oformat=binary example.o -o example

但是这似乎丢失了相对寻址值,因为使用以下命令来查看生成输出字节......

xxd example

...给出以下结果......

00000000:  ef00 0000 eff0 ffff

考虑到它是小端,这意味着与前面看到的反汇编相比,每组四个字节的顺序相反。我们可以看到第一次跳'000000ef'已经失去了它的跳跃偏移。第二次跳'fffff0ef'也不同于之前和之后应用二次赞美我们得到-1,这绝对是错误的!

有关跳转偏移如何被破坏的任何想法?我需要为链接器指定一些额外的选项来正确处理偏移吗?我找不到任何明显的东西,作为Linux和GNU的初学者,我被卡住了。

1 个答案:

答案 0 :(得分:1)

结果是链接器中存在错误,解决方法是使用...

riscv32-unknown-elf-objcopy -O binary example.o example