我编写了一个随机RISCV32I指令生成器,它可以生成十六进制格式的指令,如果需要,也可以生成二进制格式的指令。
举个简短的例子,我有:
8e900d13
00000013
0b700e13
00000013
00000013
d7400f93
仅此而已。我应该如何使用 RISCV 工具链将其编译成 ELF 或可以在仿真过程中在 RISCV 处理器上运行的东西。
一种方法是进行一些文本处理,将其转换为标准工具链的可用输入,例如 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
做到这一点很容易。