是什么原因导致RISC-V上出现SIGILL(非法指令除外)



我正试图将一些Forth加载到运行在RISC-V SBC上的Forth编译器中(但我不认为这是一个与Forth相关的问题(:

>load /root/repos/riscyforth/test2.4th
: cuboid * * [ The cuboid has a volume of ] . ;
OK
cuboid

Program received signal SIGILL, Illegal instruction.
0x0000003ff7dbd038 in ?? ()

上面显示的是,我加载了带有Forth的文件,第一行,回显到终端,是单词长方体的定义。随后的OK显示Forth编译器已成功编译该单词。

然后第二行是这个词的调用,长方体,然后是程序(在本例中在GDB下运行(已经用SIGILL兑现的消息。

然而,这就是拆解所显示的:

(gdb) disassemble 0x3ff7dbd038, 0x3ff7dbd078
Dump of assembler code from 0x3ff7dbd038 to 0x3ff7dbd078:
=> 0x0000003ff7dbd038:    addi    s9,s9,-8
0x0000003ff7dbd03c:    sd      s7,0(s9)
0x0000003ff7dbd040:    li      s8,63
0x0000003ff7dbd044:    slli    s8,s8,0x20
0x0000003ff7dbd048:    lui     t0,0xf7dbd
0x0000003ff7dbd04c:    ori     t0,t0,0
0x0000003ff7dbd050:    slli    t0,t0,0x20
0x0000003ff7dbd054:    srli    t0,t0,0x20
0x0000003ff7dbd058:    or      s8,s8,t0
0x0000003ff7dbd05c:    addi    s8,s8,112
0x0000003ff7dbd060:    mv      s7,s8
0x0000003ff7dbd062:    nop
0x0000003ff7dbd064:    lui     t0,0x10
0x0000003ff7dbd068:    addi    t0,t0,1976 # 0x107b8 <COLON_NEXT>
0x0000003ff7dbd06c:    jr      t0
0x0000003ff7dbd070:    addi    a2,sp,868
0x0000003ff7dbd072:    nop
0x0000003ff7dbd074:    unimp
0x0000003ff7dbd076:    unimp

这正是我所期望的,可以看出,0x0000003ff7dbd038有一条非常好的指令。

这个内存被作为可执行文件写入系统,这种机制对我在命令行上定义的单词很有效(而不是从文件中读取(。此外,如果我只是在我加载的文件中定义这个词,然后从命令行运行它,也没关系(我知道这些可能表明加载有问题,但我看不到它,也看不到为什么它会生成这个信号(。

更令人困惑的是,如果我使用GDB逐步完成代码,那么我就不会遇到SIGILL问题,并且从0x0000003ff7dbd038开始的代码会像我预期的那样执行。

这是RVBoards Nezha上的RV64-在此之前,执行标准的Forth解释器命令:

NEXT:
ld s8, 0(s7)            # Word address register takes content of next secondary
addi s7, s7, ADDRWIDTH  # Next secondary along
RUN:
ld t0, 0(s8)            # Extract first instruction address of primitive

与x86不同,RISC-V不允许在没有同步的情况下编写机器代码并执行它,即使在同一线程内也是如此。在执行新编写的机器代码之前,发出一条fence.i指令,使指令缓存与内存的当前状态同步。

相关内容

  • 没有找到相关文章

最新更新