C 提供了 write()、read() 等库函数用于系统调用。如何在不使用 linux 中的任何库的情况下用 C 进行系统调用?
答案1
野心或对纯度过于强烈的渴望可能会导致您进行内联组装。例如,在 x86_64 系统上,您可以执行open(2)
如下系统调用:
#include <sys/syscall.h>
int
linux_open(const char *pathname, unsigned long flags, unsigned long mode)
{
long ret;
asm volatile ("syscall" : "=a" (ret) : "a" (__NR_open),
"D" (pathname), "S" (flags), "d" (mode) :
"cc", "memory", "rcx",
"r8", "r9", "r10", "r11" );
if (ret < 0)
{
errno = -ret;
ret = -1;
}
return (int) ret;
}
你可以查看更易理解的 libc 的源代码(例如穆斯尔)来了解系统调用是如何实现的。
答案2
为了进行系统调用,您通常必须在 CPU 上执行一些不属于 C 语言规范的函数。系统调用要么以 CPU 的汇编语言编写并链接,要么使用 C 函数内的某些 CPU 特定的内联汇编。
Linux 内核中定义了各种宏来支持这一点,因为所有系统调用都需要非常相似的设置。结果是,通常很难清楚 CPU 特定的汇编程序实际上来自哪里,但如果你挖掘得足够深,你就会明白它。