如何将十六进制编码的指令编译成ELF用于RISCV模拟?

问题描述 投票:0回答:1

我编写了一个随机RISCV32I指令生成器,它可以生成十六进制格式的指令,如果需要,也可以生成二进制格式的指令。

举个简短的例子,我有:

8e900d13

00000013

0b700e13

00000013

00000013

d7400f93

仅此而已。我应该如何使用 RISCV 工具链将其编译成 ELF 或可以在仿真过程中在 RISCV 处理器上运行的东西。

assembly compilation riscv machine-code
1个回答
0
投票

一种方法是进行一些文本处理,将其转换为标准工具链的可用输入,例如 GAS (GNU binutils) 或 clang。

sed 's/^/.word 0x/' foo.hex > foo.s
会将您的十六进制转换为像
.word 0x8e900d13
这样的 asm 源,您可以使用标准工具进行组装。汇编器读取源代码行并将字节组装到输出文件的当前部分,并且不关心源代码行是
li  s10, -1815
addi s10, x0, -1815
还是
.word 0x8e900d13
,或者使用
.byte
相同。

周围有一些附加文本,如

_start:
/
.global _start
,您可以拥有一个源文件,您可以使用一些选项与
gcc
进行有用的汇编和链接。


例如,跳过空白行(或其他不仅仅是可选空格和字母数字字符的行)。

sed -E
使用扩展正则表达式,因此
+
是一个或多个重复,与默认的基本正则表达式不同。
\s*
是 0 个或多个空白字符。初始
/pattern/
仅将规则应用于匹配行,
s/pat/subs/
将行的开头(以及任何初始空白)替换为
.word 0x

$ sed -E '/^\s*[[:alnum:]]+/  s/^\s*/.word 0x/' foo.hex > foo.s
$ cat foo.s
.word 0x8e900d13

.word 0x00000013

.word 0x0b700e13

.word 0x00000013

.word 0x00000013

.word 0xd7400f93
$ clang -target riscv32 -c foo.s
$ llvm-objdump -d foo.o

foo.o:  file format elf32-littleriscv

Disassembly of section .text:

00000000 <.text>:
       0: 13 0d 90 8e   li      s10, -1815
       4: 13 00 00 00   nop
       8: 13 0e 70 0b   li      t3, 183
       c: 13 00 00 00   nop
      10: 13 00 00 00   nop
      14: 93 0f 40 d7   li      t6, -652

当然,您可以让指令生成器输出像

.word 0x...
这样的 asm 源,而不是单独执行此操作。并选择您最喜欢的文本处理工具来完成此任务;如果您熟悉老式 Unix 工具,
sed
做到这一点很容易。

© www.soinside.com 2019 - 2024. All rights reserved.