![可执行文件如何使用 POSIX 来保持不同 UNIX 系统之间的兼容性?](https://linux22.com/image/229799/%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20POSIX%20%E6%9D%A5%E4%BF%9D%E6%8C%81%E4%B8%8D%E5%90%8C%20UNIX%20%E7%B3%BB%E7%BB%9F%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%BC%E5%AE%B9%E6%80%A7%EF%BC%9F.png)
在我的理解中,POSIX只指定了操作系统需要提供的一组API,但它没有指定实现细节,特别是程序集级别的兼容性。例如,在 x86 上,您需要使用系统调用来获取 POSIX API:
1. set `eax` to the syscall number
2. set syscall arguments
3. call int 0x80
但这个过程可能会有很大差异,具体取决于:
- UNIX 操作系统:不同的操作系统可以有不同的从系统调用号到 POSIX API 的映射
- 架构:X86/arm有不同的指令调用
int 0x80
所以我认为 POSIX 通过在不同操作系统中保留 POSIX 库的 API 转换来完成其工作。例如glibc.so
:
POSIX API 以 glibc 符号形式提供。每次可执行文件调用 POSIX API 时,它都会在每个操作系统中查找该符号glibc.so
,并且无需直接在可执行文件中调用 int 0x80。
所以我的问题是:
- 我的理解正确吗?
- 除此之外
glibc.so
,是否还有其他库的行为类似glibc.so
但在不同的 UNIX 操作系统中?
答案1
POSIX没有指定二进制接口,因此您无法构建“POSIX”二进制文件并在不同的 POSIX 风格操作系统上运行它。 POSIX 甚至不关心系统调用;它定义了函数,这些函数最终在哪里实现并不重要。
实际上,正如您提到的,在 Linux 和其他 POSIX 风格的系统上,这些函数是在“C 库”中实现的。但甚至没有 POSIX 定义的方式让二进制文件调用这些函数; C 程序的 POSIX 在编写和编译程序以及考虑运行时系统接口的行为时最相关,但并不那么重要如何访问这些接口。命令c99
指定运行编译器,因此 POSIX 中要求能够获取 C 源代码并将其转换为二进制文件,但该二进制文件的详细信息是特定于系统的。 (Linux 上的二进制接口遵循称为系统 V ABI,具有各种特定于体系结构的扩展。)
还有其他 C 库。每个平台都提供自己的,有些平台有多个。在Linux上,有GNU C 库, 但是也穆斯勒。
另请注意,C 库不仅用于 C 程序,还用于 C 程序。在 POSIX 风格的系统上,大多数编译器和解释器最终都会使用它。 (值得注意的例外包括 Go 二进制文件,它们实现了自己的内核用户空间 API 接口。)