pk / Linux上的RISC-V ecall syscall调用约定

时间:2020-01-18 12:06:26

标签: system-calls calling-convention riscv

在RISC-V伪内核(pk)或Linux下运行的程序中,系统调用的调用约定是什么?

看看riscv-gnu-toolchain生成的代码,规则似乎是:

  • 系统调用号在a7中传递
  • syscall参数在a0中传递给a5
  • 未使用的参数设置为0
  • 返回值在a0中返回

是这个吗?

真的有必要将未使用的参数归零吗?

寄存器a6呢?可以将其用于另一个sycall参数吗?

调用exit()系统调用的示例:

li    a0, 1               # argument that is used by the syscall
li    a1, 0               # unused arguments
li    a2, 0
li    a3, 0
li    a4, 0
li    a5, 0
li    a7, 93              # exit syscall number

1 个答案:

答案 0 :(得分:4)

是的,基本上就是这样。

否,没有必要将未使用的参数清零。使用riscv-gnu-toolchain(带有newlib C库)时,将未使用的参数清零只是newlib sycall调用代码的产物。为简单起见,该代码有一个带有6个syscall参数的scall (old name for ecall) wrapper。因此,exit()实现只是calls that wrapper with some additional zeroes

截至2020年,maximum number of syscall arguments in Linux is 6。伪内核也是如此。因此,a6始终未使用。

Linux和pk均在a7中提供系统调用号。 pk使用的syscall编号遵循Linux标准。

syscall(2) Linux手册页还总结了包括RISC-V在内的不同体系结构的调用约定。 specifies a1可能用于返回第二个返回值,但这与glibc和newlib中的代码不匹配。