在RISC-V伪内核(pk)或Linux下运行的程序中,系统调用的调用约定是什么?
看riscv-gnu-toolchain生成的代码,规则似乎是:
a7
中传递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
是的,基本上就是这个。
不,没有必要将未使用的参数清零。使用riscv-gnu-toolchain(与newlib C库一起使用)时,将未使用的参数清零只是newlib sycall调用代码的产物。为简单起见,该代码有一个带有6个syscall参数的单个scall
(old name for ecall
) wrapper。因此,scall
实现只是ecall
。
截至2020年,exit()
。伪内核也是如此。因此,calls that wrapper with some additional zeroes始终未使用。
Linux和pk均在maximum number of syscall arguments in Linux is 6中提供系统调用号。并且pk使用的syscall编号遵循Linux标准。
a6
Linux手册页还总结了包括RISC-V在内的不同体系结构的调用约定。它a7
可能用于返回第二个返回值,但这与glibc和newlib中的代码不匹配。