如果给定正确的运行时库,x86 可执行文件是否可以在任何 x86 平台上运行

Can an x86 executable run on any x86 platform given the right runtime libraries?

本文关键字:x86 是否 任何 运行 平台 可执行文件 如果 运行时      更新时间:2023-10-16

虽然我确实发现了类似的问题,但他们并没有真正回答这个具体问题。

在给定正确的运行时库的情况下,编译的 x86 可执行文件是否可以在任何 x86 平台上运行? 假设我制作了一个没有依赖项的C++17 程序,我可以在 Windows 95 上运行这个程序还是操作系统需要某种支持?

我还听说 RTTI(在 C++ 的情况下)可能并非在所有地方都受支持,这仅仅是因为处理器必须支持此功能还是操作系统在其中发挥作用?这意味着Windows 95等可能不支持新功能。

编辑

我所追求的是可执行文件(例如,x86)是否可以在支持该指令集的任何平台上运行,或者某些功能(如RTTI)是否需要特定的操作系统支持,因此并非在所有支持该指令集的平台上都可用。

一般来说,即使你将你的宇宙限制在 x86 硬件上,你也不能- 至少没有对二进制文件进行一些转换或为每个目标平台提供一些特定于平台的"加载器"。

例如,C 或 C++ 编译器1发出的典型二进制文件对操作系统和运行时的依赖性最小,例如加载可执行文件并在可执行文件上进行运行时链接。不同的平台有不同的二进制格式(例如Windows上的PE/COFF或各种UNIX风格和Linux的ELF),并且没有任何通用的"x86格式"可以直接在任何平台上工作。

此外,任何非平凡的程序,在许多情况下,任何程序,无论是否平凡,都将对语言运行时具有特定于平台的依赖关系。例如,即使是空的main()函数也经常需要运行时支持才能从操作系统定义的"start"方法获取到main方法,并且如果没有异常的构建选项,则在启动时经常调用以初始化标准库的某些部分。

最后,正如您在关于RTTI的评论中提到的,各种语言或平台功能基本上可以编译成二进制文件,并且需要操作系统支持。RTTI 可能显然不属于这一类,但诸如位置无关的代码、线程本地存储和对异常处理的堆栈展开支持之类的东西通常属于这一类。使用此类功能的编译 x86 代码在不同的平台上可能大不相同,因为它需要构建这些功能如何工作的假设。

但是,原则上,您可以想象这是有效的,至少对于某些有限的程序子集。例如,虽然各种可执行格式在实践中不兼容,但它们并没有那么不同,并且存在可以在它们之间进行转换的工具。因此,您当然可以在感兴趣的平台上实现最小运行时,该运行时将x86可执行文件编译为您选择的任何固定格式,并在运行时转换为本地格式并运行它。

除此之外,实际上尝试映射标准库调用将非常困难,因为不同的操作系统使用不同的调用约定,但是"C"函数可以使用一些thunks将东西放在正确的位置。C++几乎是正确的,因为那里的 ABI 要复杂得多,特定于编译器和平台,并且大部分实现细节已经编译为标头中实现的内容。

事实上,x86的子集可能为跨平台执行提供一种有趣的中间语言的想法正是Google的[NaCl项目]所利用的想法。从本质上讲,NaCl 运行时提供了与平台无关的"加载"功能,允许 x86 代码在各种平台上或多或少地本机运行。随后添加了其他本机格式,例如ARM,但它最初是x86沙箱。该项目的很大一部分涉及运行可证明安全(即沙盒)的代码 - 但它表明,使用某些基础架构,您可以编写"可移植"的x86。但是,标准的 C 或 C++ 编译器不会直接发出与 NaCl 兼容的代码。


1实际上,任何编译为本机格式的编译器。我只是叫C和C++,因为它们似乎是你感兴趣并且广为人知的。

这个问题没有抓住重点。C++首先是一种描述计算机程序行为的语言。

使用编译器创建本机二进制可执行文件以在实际计算机上生成该行为是使用该语言的典型方式。

一旦你有了二进制文件,用于生成它的源代码的所有痕迹都消失了(除非你已经构建了一个特殊的版本来调试)。二进制文件与特定硬件或操作系统的兼容性超出了C++本身的范围。

对于 C 或任何其他通常编译为本机二进制代码的编程语言也是如此。

或者,更简短地回答这个问题:

编译的 C++/C 代码(即可执行文件)可以在正确的运行时库的任何地方运行吗?

不。

在给定正确的运行时库的情况下,编译的 x86 可执行文件可以在任何地方运行吗?

不可以,它仅适用于 x86 硬件或模拟 x86 指令集的其他硬件(或软件,例如虚拟机)(例如 x64 CPU)。 实际上,这很可能与"任何地方"相去甚远。

即使硬件匹配,x86 可执行文件也将具有操作系统依赖项。 Windows二进制文件不会在Linux上运行,即使硬件相同。 在某些情况下,有各种策略可以使这样的事情"工作",Microsoft的WindowsLinux子系统是最近的一个例子,它允许Linux二进制文件在Windows上保持不变地运行。 再次,来自"任何地方"的炸薯条哭声。