OS 库是用汇编语言还是 C 语言编写的

Are OS libraries written in assembly or in C

我问这个,因为我对系统调用的定义非常矛盾。

一方面,我看到他们的定义是API OS 规定用户程序可以调用。由于这个 API 是一个高级接口,它必须用像 C 这样的高级语言来实现。

另一方面,我看到实际的 OS 系统调用是机器指令,为此您必须设置某些寄存器来调用(根据 OS ).但这看起来与 UNIX API 中的 open()、write() 和 read() 完全不同,所以这里发生了什么。

我还了解到这些高级接口是在执行实际汇编代码系统调用的 C 库中实现的。既然如此,为什么说OS提供了这个接口,而实际上是C语言提供的呢。如果我想直接对 OS 执行 UNIX 系统调用而不必使用 C,该怎么办?

有两个open函数——一个是操作系统公开的系统调用open(例如Linux),另一个是C库函数open, 由 C 标准库(例如 glibc)公开。

您可以查看这些函数的两个不同的手册页 - 运行 man 2 open 查看有关系统调用的手册页,man 3 open 查看有关 C 标准的手册页功能。


您提到的 openwriteread 等函数可能会造成混淆 - 因为它们既作为系统调用又作为 C 标准函数存在。但它们完全是独立的实体 - 事实上,glibc 的 open 函数 甚至不使用 open 系统调用 - 它使用 openat 系统调用。

在 Windows 上,系统调用 open 甚至不存在 - C 标准库函数 open 仍然存在,并在幕后使用 WinAPI 的 CreateFile


What if I want to perform a UNIX syscall directly to the OS without having to use C?

这是可能的——事实上,glibc 必须这样做才能实现 C 标准库函数。但这很棘手,涉及为系统调用实现包装器,有时甚至需要手工组装。


如果你想亲眼看看,可以看看how glibc implements open:

int
__libc_open (const char *file, int oflag, ...)
{
  int mode = 0;
  if (__OPEN_NEEDS_MODE (oflag))
    {
      va_list arg;
      va_start (arg, oflag);
      mode = va_arg (arg, int);
      va_end (arg);
    }
  return SYSCALL_CANCEL (openat, AT_FDCWD, file, oflag, mode);
}
...
weak_alias (__libc_open, open)

请注意,该函数以调用宏 SYSCALL_CANCEL 结束,这将最终调用 OS-公开的 openat 系统调用。

很少有人直接用汇编写东西。通过用 C 语言编写,您可以为许多不同的 CPU 架构编译它,而通过用汇编语言编写,您基本上只能使用一种特定的架构。大多数操作系统都是用 C 编写的。我们说 OS 提供了接口,因为您正在与恰好用 C 编写的操作系统进行交互。

Are OS libraries written in assembly or in C

这是一个无法真正回答的问题,视情况而定。从技术上讲,对实现没有限制(即它可以用任何语言编写,尽管 C 可能是最常见的,其次是汇编)。

这里的重要部分是 ABI。这定义了如何进行 OS 调用。

您可以在汇编中进行系统调用(如果您知道 ABI,您可以手动编写所有代码以符合要求),C 编译器知道 ABI 并将自动生成进行调用所需的所有代码。

大多数语言虽然允许您进行系统调用,但它们要么知道 ABI,要么有一个包装器 API 将调用从语言调用转换为该 OS 的适当 ABI。


I ask this, because I am getting very conflicting definitions of System calls.

定义将取决于上下文。您必须举例说明 AND 在什么上下文中使用的定义。


One one hand, I have seen the definition that they are an API the OS provides that a user program can call.

当然这是一种看待它的方式。

更严格地说,我认为 OS 提供了一组可用于执行特权任务的接口。现在,这些接口可以通过特定环境提供的 API 公开,使它们更易于使用。


Since this API is a high level interface, it has to be implemented in a high level language like C.

有点真实。

一个环境可以暴露一个API并不代表它需要高级语言(而且C不是高级语言,它比汇编高一级,算是低级语言) .仅仅因为它由语言公开并不意味着它是用该语言实现的。


On the other hand, I have seen that the actual OS syscalls are machine instructions, for which you have to set certain registers to call (according to some compliance standard set by the OS).

好的。这里我们已经从 System Calls 移动到 syscalls。我们在使用这些术语时应该非常小心,以确保我们不会混淆不同的术语。

我会(这仍然有点抽象)将计算机视为几个抽象级别:

                      Hardware 
        ------        --------------
                      syscalls
          OS          --------------
                      System Calls       (read/write etc..)
        ------        --------------
                      Language Interface (read/write etc..)

如果你愿意,你可以直接戳硬件(如果你知道怎么做),但如果你能进行系统调用会更好(如果你知道怎么做),但最好使用 OS 系统调用它使用定义良好的 ABI,但最好使用语言接口(你称之为 API)来调用底层系统调用。


But this looks nothing like the UNIX APIs like open(), write() and read(), so what is going on here.

此处 UNIX OS 提供 open/close/read 接口。

C 库在 OS 系统调用之上提供了一个非常薄的 API 包装器接口。然后,C 编译器将生成正确的指令,以使用正确的 ABI 调用系统调用,进而调用 OS 中的下一层以使用系统调用。


I have also read that these high level interfaces are implemented in the C libraries which do the actual assembly code syscalls.

高级接口可以用任何语言编写。但是 C 语言非常容易使用,以至于大多数其他语言都懒得自己动手,只需通过 C 接口调用即可。