API 中的函数是自己进行系统调用还是由 API 进行的系统调用是由运行时支持系统中的系统调用接口辅助的?

Does functions in API make system calls themselves or system calls made by API are aided by system-call interface in the runtime support system?

我正在阅读 Galvin 的恐龙书,在那里我遇到了问题中提出的困难。

Typically application developers design programs according to an application programming interface (API). The API specifies a set of functions that are available to an application programmer, including the parameters that are passed to each function and the return values the programmer can expect.

文中补充说:

Behind the scenes the functions that make up an API typically invoke the actual system calls on behalf of the application programmer. For example, the Win32 function CreateProcess() (which unsurprisingly is used to create a new process) actually calls the NTCreateProcess() system call in the Windows kernel.

从以上两点我了解到:程序员使用API,对API的函数调用与他们想进行的系统调用相对应。 API 中的相关函数然后实际进行系统调用。

接下来文字说的让我有点困惑:

The run-time support system (a set of functions built into libraries included with a compiler) for most programming languages provides a system-call interface that serves as the link to system calls made available by the operating system. The system-call interface intercepts function calls in the API and invokes the necessary system calls within the operating system. Typically, a number is associated with each system call, and the system-call interface maintains a table indexed according to these numbers. The system call interface then invokes the intended system call in the operating-system kernel and returns the status of the system call and any return values.

上面的摘录让我觉得API中的函数并没有直接进行系统调用。运行时支持系统的系统调用接口中可能内置了一些函数,这些函数正在等待API.[=19]中的函数系统调用事件=]

以上是文中解释系统调用接口工作原理的图

后面的文字解释了C标准库中系统调用的工作原理如下:

说的很清楚了。

我不完全理解您分享的摘录中的术语。一些术语也是错误的,例如底部的蓝色图像。它说标准 C 库提供了系统调用接口,但它没有。标准 C 库只是一个标准。这是一个约定。它只是说,如果你写了一段代码,那么这段代码在运行时的效果应该是按照约定的。它还说 C 库会拦截 printf() 调用,而它不会。这是一般术语,充其量是令人困惑的。

C 库不拦截调用。例如,在 Linux 上,C 标准库的开源实现是 glibc。您可以在这里浏览它的源代码:https://elixir.bootlin.com/glibc/latest/source。当您编写 C/C++ 代码时,您使用的是 C/C++ 约定中指定的标准函数。

当您编写代码时,此代码将被编译为汇编,然后再编译为机器代码。汇编也是机器代码的更高级别表示。它只是更接近实际代码,因为它比 C/C++ 更容易 t运行slate 到它。最容易理解的情况是静态编译代码。当您静态编译代码时,所有代码都包含在您的可执行文件中。例如,如果您写

#include <stdio.h>
int main() {
   printf("Hello, World!");
   return 0;
}

printf() 函数在 stdio.h 中被调用,它是 gcc 提供的头文件,专门为一个 OS 或一组类 UNIX OS 编写。此头文件提供了在 glibc 提供的其他 .c 文件中定义的原型。这些 .c 文件提供了 printf() 的实际实现。 printf() 函数将进行系统调用,它依赖于 OS 的存在,例如 Linux 到 运行。静态编译时,代码全部包含在系统调用之前。你可以在这里看到我的回答:。它专门解释了如何进行系统调用。

最后你会得到类似汇编代码的东西,将一些参数推入一些常规寄存器,然后是跳转到 MSR 的实际 syscall 指令。我不完全理解 printf() 背后的机制,但它会跳转到 Linux 内核对 write 系统调用的实现,该系统调用将写入控制台和 return.

我认为让您感到困惑的是“运行time-support system”可能指的是更高级的语言,它们不会像 Python 或 [=33= 那样直接编译为机器码]. Java 有一个虚拟机,它 运行 在 运行 期间使用虚拟机将编译生成的字节码转换为机器码。在谈论不同的语言时不进行这种区分可能会造成混淆。也许你的书缺少例子。