我开始学习riscv。我得到了qemu-riscv,riscv-gcc并编译了下一个hello world asm程序:
.section .text
.globl _start
_start:
li a0, 0 # stdout
1: auipc a1, %pcrel_hi(msg) # load msg(hi)
addi a1, a1, %pcrel_lo(1b) # load msg(lo)
li a2, 12 # length
li a3, 0
li a7, 64 # _NR_sys_write
ecall # system call
li a0, 0
li a1, 0
li a2, 0
li a3, 0
li a7, 93 # _NR_sys_exit
ecall # system call
loop:
j loop
.section .rodata
msg:
.string "Hello World\n"
这里使用的是系统调用(_NR_sys_write,_NR_sys_exit),这让我感到困惑-我认为我运行的是“裸机”程序,但是为什么隐式使用了系统调用?为什么此系统调用由qemu代理,如果我在没有强制性的系统调用的fpga riscv上运行此代码,将会发生什么情况?
ps:真的很难为我找到任何risc-v编程教程或处理器裸机配置。移植的操作系统(FreeRTOS,Linux和FreeBSD)的代码注释很少,但是没有任何解释。您还能为我提供此信息吗?
答案 0 :(得分:1)
QEMU中有三个目标系列:
ecall
时,它将解码系统调用号/参数,执行系统调用,然后返回仿真指令。因此,QEMU的用户模式仿真与特定主管的ABI相关联,而我在RISC-V领域中看到的唯一实例是Linux。ecall
时,它将开始在陷阱矢量处仿真代码。由于确切的主管代码正在运行,因此QEMU不需要了解有关主管的任何信息。如果您在用户空间中看到ecall
指令运行正常,那么您可能正在用户模式仿真中运行。