我正在尝试编写一个非常轻量级的 libc 替换库,以便更好地理解内核 - 应用程序接口。第一个任务显然是让一些系统调用包装器到位。我已经成功地让 1 到 3 个参数包装器工作,但我正在努力处理 4 个参数变量。这是我的出发点:
long _syscall4(long type, long a1, long a2, long a3, long a4)
{
long ret;
asm
(
"syscall"
: "=a"(ret) // return value
: "a"(type), "D"(a1), "S"(a2), "d"(a3), "r10"(a4)
: "c", "r11", "memory" // some syscalls read or write memory
// the syscall insn instruction itself destroys RCX and R11
);
return ret;
}
(编者注:这是安全且可用的,并且是一个很好的例子,在应用答案的方式来处理之后r10
。MUSL libc 有一些类似的宏。)
编译器给我以下错误:
error: matching constraint references invalid operand number
我的 _syscall3 函数工作正常,但不使用 r10 或有一个clobber 列表。
(编者注:没有clobber列表是不安全的:您需要告诉编译器RCX和R11被覆盖,并且“内存”应该在可能读取或写入内存的系统调用之前同步。如果如果您想为特定的系统调用编写特定的包装器,您可以有选择地省略"memory"
clobbers,或者根据哪些参数是该系统调用的指针来使用虚拟内存操作数。
如果这个_syscall4
函数不能内联,寄存器和"memory"
clobbers实际上不会造成任何问题,但你应该让它们能够内联;与调用非内联包装函数相比,内联此系统调用在调用站点需要的代码更少。)