【问题标题】:Can an x86 executable run on any x86 platform given the right runtime libraries?给定正确的运行时库,x86 可执行文件可以在任何 x86 平台上运行吗?
【发布时间】:2017-08-16 10:01:22
【问题描述】:

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

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

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

编辑

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

【问题讨论】:

  • @Ðаn 我最好指定问题。我的意思是编译后的可执行文件
  • 我看到有人使用 C++14 为 commodore 64 编写 pong。你需要一个可以为目标机器构建的编译器。
  • 不,它可能无法在不兼容的操作系统上运行。除非它可以在某种类型的仿真容器中运行。不兼容的 CPU 也是如此。
  • @Ðаn 我想 C-goers 也厌倦了在他们的队列中看到 coutusing namespace std;
  • @BeeOnRope:实际上,它慢慢变得合理了。查看编辑历史记录。

标签: c++ windows x86 executable compiled


【解决方案1】:

一般你不能,即使你将你的 Universe 限制为 x86 硬件 - 至少在没有为每个目标平台进行二进制转换或一些特定于平台的“加载器”的情况下不能。

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

此外,任何不平凡的程序以及在许多情况下任何程序,无论是否平凡,都会对语言运行时具有特定于平台的依赖性。例如,即使是一个空的 main() 函数,通常也需要运行时支持才能从 OS 定义的“start”方法到 main 方法,并且在没有异常构建选项的情况下,通常会在启动时调用来初始化标准库的某些部分。

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

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

除了实际尝试映射标准库调用将非常困难,因为不同的操作系统使用不同的calling conventions,但是“C”函数可以使用一些 thunk 将东西放在正确的位置。 C++ 几乎完全正确,因为那里的 ABI 更复杂,编译器和平台特定,并且大部分实现细节已经编译在头文件中实现的东西。

事实上,x86(的一个子集)可能为跨平台执行提供有趣的中间语言的想法正是谷歌 [NaCl 项目] 中利用的想法。从本质上讲,NaCl 运行时提供了与平台无关的“加载”功能,允许 x86 代码或多或少地在各种平台上本地运行。随后添加了其他本机格式,例如 ARM,但它最初是作为 x86 沙箱。该项目的很大一部分处理可证明安全的运行代码(即沙盒) - 但它表明通过一些基础设施您可以编写“便携式”x86。然而,标准的 C 或 C++ 编译器不会直接生成与 NaCl 兼容的代码。


1 真的,any 编译器编译为本机格式。我只提到 C 和 C++,因为它们看起来像是您感兴趣且广为人知的。

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    没有。

    【讨论】:

    • 我觉得这不能回答这个问题。我知道在编译可执行文件后,源语言的所有痕迹都消失了。我只想知道编译后的可执行文件是否需要操作系统对某些功能(如 RTTI)的支持,或者它是否只需要正确的运行时库
    • @itzJanuary:是的,我同意这个答案对于现在的问题来说有点偏离主题;在所有编辑之前,它对 original 问题更有效。它基本上仍然是正确的,并且得到了一些支持,这意味着有人发现它在某些方面很有价值,所以我把它留在这里而不是删除它。
    【解决方案3】:

    如果有正确的运行时库,编译后的 x86 可执行文件可以在任何地方运行吗?

    不可以,它只能在 x86 硬件或模拟 x86 指令集(例如 x64 CPU)的其他硬件(或软件,例如虚拟机)上运行。在实践中,这很可能与“任何地方”相去甚远。

    即使硬件匹配,x86 可执行文件也将具有操作系统依赖性。即使硬件相同,Windows 二进制文件也不会在 Linux 上运行。在某些情况下,有多种策略可以使这样的事情“工作”,微软的Linux Subsystem for Windows 是最近的一个例子,它允许 Linux 二进制文件在 Windows 上运行不变。再一次,从“任何地方”传来一声炸响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-19
      • 2012-11-18
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多