为什么可执行文件依赖于操作系统
在本文中,我们将讨论为什么可执行文件依赖于操作系统,并将详细讨论原因。并且还将讨论提高兼容性的方法。让我们一一讨论。
为什么可执行文件依赖于操作系统:
如下所示,执行可执行文件需要 OS 和 CPU。
- CPU根据一个或多个指令集对可执行文件中的二进制指令进行解码。大多数消费者 CPU 都支持 x86(“32 位”)和 AMD64(“64 位”)指令集。可以为这些指令集之一编译程序,但不能同时为这两个指令集编译程序。这些指令集的扩展是可用的,并且可以在运行时检查对它们的支持。
- SIMD 支持就是这种扩展的一个例子。如果存在这些扩展,优化编译器可能会尝试使用它们,但它们通常也会提供一个无需它们即可工作的代码路径。
- 系统 API:程序可能会使用必须安装在目标系统上的库。使用 Windows API 函数的软件不能在 Linux 上运行。在 Unix 世界中,中央操作系统 API 已标准化为 POSIX:完全使用 POSIX 函数编写的程序将在支持它们的任何 Unix 系统上运行,包括 Mac OS X 和 Solaris。
- 二进制格式:可执行文件必须遵循特定的二进制格式,以便操作系统正确加载、初始化和启动程序。 Portable Executable 格式在 Windows 上被广泛使用,而 ELF 在 Linux 上被广泛使用。
结果 :
因此,如果两个系统具有相同的系统 API 和库,在相同的指令集上运行,并使用相同的二进制格式,那么为一个系统编写的程序将在另一个系统上运行。
但是,有一些方法可以提高兼容性:
x86 可执行文件通常在 AMD64 指令集上运行。二进制格式指定应使用哪种模式。操作系统必须付出额外的努力来处理 32 位和 64 位应用程序。某些二进制格式允许将程序的多个副本存储在单个文件中,每个副本针对不同的指令集进行编码。 Apple 在从 Power-PC 架构过渡到 x86 架构时提倡使用“胖二进制文件”。
- 一些程序被编译为中间形式而不是机器代码。然后将其即时转换为实际指令,或者可以理解。这允许程序独立于其体系结构。在 UCSD p-System 上,使用了这种方法。
- 99% 的现代 Windows PC 都使用 64 位 CPU,它们也可以执行 32 位软件。剩下的 1% 使用 32 位 CPU。因此,为 32 位 CPU 编写的软件被广泛使用。专为 64 位处理器设计的软件可以在软件设计者关心的任何 PC 上运行。
笔记 -
可执行文件不仅仅包含原始机器代码。当操作系统加载它时,它会读取它并确定它应该如何运行。编译时,通常会指定一个目标CPU;如果您不这样做,编译器将使用您当前的 CPU 并限制自己仅选择您的 CPU 及其旧版本通用的指令。如果您想使用仅在目标 CPU 的特定修订版上可用的新指令,您可以告诉编译器或使用内部或内联汇编代码对其进行手动编码。但是,如果您在不支持该指令的 CPU 上运行您的程序,它将崩溃。