为什么可执行文件依赖于操作系统而不依赖于CPU?


16

如果我编写C程序并将其编译为.exe文件,则该.exe文件包含对CPU的原始机器指令。(我认为)。

如果是这样,我怎么可能在运行现代Windows版本的任何计算机上运行编译的文件?每个CPU系列都有不同的指令集。那么.exe,无论使用哪种物理CPU,任何运行适当操作系统的计算机都可以理解我文件中的指令?

同样,通常在某些应用程序“下载”页面上的网站上,您可以下载Windows,Linux和Mac(对于每个操作系统,对于86和64位计算机,通常为两次下载)。为什么每个CPU系列的下载量都没有增加?


4
CPU具有x86、64b等标准。可执行文件确实取决于CPU。您无法在RISC等特殊CPU上运行您提到的exe,也有大量特殊用途的CPU
InformedA 2014年

操作系统由可执行文件组成,它们取决于CPU,而不取决于OS,因为它们是OS。
图兰斯·科尔多瓦

因为向后兼容。
MiKL'1

2
对于86和64位计算机,通常每个操作系统都有两次下载:我将其解释为对CPU可执行文件的依赖。
mouviciel

Answers:


37

可执行文件的确取决于操作系统和CPU:

  • 指令集:可执行文件中的二进制指令由CPU根据某些指令集解码。大多数用户CPU支持x86(“ 32位”)和/或AMD64(“ 64位”)指令集。可以为这两个指令集之一编译程序,但不能同时为这两个指令集编译程序。这些指令集有扩展。可以在运行时查询对它们的支持。例如,此类扩展提供SIMD支持。如果存在这些扩展,优化编译器可能会尝试利用这些扩展,但通常也提供了无需任何扩展即可工作的代码路径。

  • 二进制格式:可执行文件必须符合某种二进制格式,这样操作系统才能正确加载,初始化和启动程序。Windows主要使用Portable Executable格式,而Linux使用ELF。

  • 系统API:程序可能正在使用执行系统上必须存在的库。如果程序使用Windows API的功能,则不能在Linux上运行。在Unix世界中,中央操作系统API已被标准化为POSIX:仅使用POSIX功能的程序将能够在任何兼容的Unix系统上运行,例如Mac OS X和Solaris。

因此,如果两个系统提供相同的系统API和库,在相同的指令集上运行并使用相同的二进制格式,则为一个系统编译的程序也将在另一个系统上运行。

但是,有一些方法可以实现更高的兼容性:

  • 在AMD64指令集上运行的系统通常也会运行x86可执行文件。二进制格式指示要运行的模式。处理32位和64位程序都需要操作系统付出额外的努力。

  • 一些二进制格式允许文件包含为不同指令集编译的程序的多个版本。苹果在从PowerPC架构过渡到x86时鼓励了这种“胖二进制文件”。

  • 有些程序不是编译为机器代码,而是编译为某些中间表示。然后将其即时翻译为实际说明,或者可能被解释。这使程序独立于特定体系结构。UCSD p系统上使用了这种策略。

  • 一个操作系统可以支持多种二进制格式。Windows非常向后兼容,仍然支持DOS时代的格式。在Linux上,Wine允许加载Windows格式。

  • 可以为另一个主机OS重新实现一个操作系统的API。在Windows上,可以使用Cygwin和POSIX子系统来获得(主要是)POSIX兼容的环境。在Linux上,Wine重新实现了许多Windows API。

  • 跨平台库允许程序独立于OS API。许多编程语言都有尝试实现此目的的标准库,例如Java和C。

  • 一个仿真器通过解析国外二进制格式,解释说明,并提供所有必需的API的重新实现模拟不同的系统。模拟器通常用于在现代PC上运行旧的Nitendo游戏。


10
您应该提到java和.net都是使用中间格式的示例-中间格式在今天非常流行,而不仅仅是1970年系统的遗迹,后者的软盘数量为5 1/4。
jmoreno,2014年

@AKoscianski感谢您的建议编辑。但是,我认为安全性设计不是可执行文件依赖于操作系统的原因,而是我们首先将操作系统与用户区分开的原因。此答案的“系统API”部分已经解决了与受保护的操作系统功能不同的API。
amon

2

当前运行Windows的PC中有99%具有64位处理器,该处理器还能够运行32位软件。其余百分之一具有32位处理器。因此,为32位处理器构建的软件随处可见。为64位处理器构建的软件可在软件创建者关心的每台PC上运行。

MacOS X和iOS支持“胖二进制文件”-您实际下载的内容可以包含不同处理器的版本。不再有人为PowerPC处理器构建应用程序,但是几年前的某个时候,可执行文件可能包含PowerPC,32位Intel和64位Intel版本,并且正确的可执行文件将被执行。如今在iOS上,下载应用程序时,您将获得适合设备上处理器的版本。在其他设备上下载,您将获得不同的版本。对用户完全不可见。


-1

exe不仅包含原始机器代码,还包含更多信息。操作系统在加载时会读取此信息,并可以确定应如何运行。

编译时,通常会设置目标CPU,如果不设置目标CPU,则编译器会选择当前的CPU,并将其自身限制为只能选择与您的CPU及其较旧版本通用的指令。如果要使用特定于目标CPU特定修订版的新指令,则可以告诉编译器,也可以使用内部函数或内联汇编代码手动对其进行编码。但是,如果程序在不支持该指令的CPU上运行,则该程序将崩溃。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.