C ++编译器将您的代码编译成可执行文件(.exe),该文件包含由CPU命令组成的CPU可读机器代码。不同的CPU具有不同的体系结构和可能不同的命令。如果CPU具有不同的命令,则为我的CPU编译的可执行文件可能无法在具有另一种具有另一种体系结构和另一条命令的CPU的另一台计算机上运行。对于示例,将在 SkyLake 内核上运行的程序在 KabyLake 内核上运行,并在 Intel CPU 上运行的程序在< strong> AMD CPU 。我对吗?如果是这样,有什么方法可以在计算机上用正确的命令安装正确的可执行文件?另请在示例中回答问题。
答案 0 :(得分:5)
您是正确的。编译器的输出是机器代码,并且不同的CPU体系结构具有不同的指令集,需要不同的机器代码。因此,x86机器代码将无法在基于ARM的CPU上运行。
除了编译器正在运行的CPU之外,编译器还可能输出CPU的机器代码。通常将其称为“交叉编译”,所有主要的C ++编译器都在某种程度上具有此功能。
还请注意,可执行文件 只是一个包含机器代码的文件。操作系统的程序加载器负责将机器代码从文件加载到内存中,并开始实际执行。因此,在一个可执行文件中完全有可能具有用于多种CPU架构的机器代码。例如,MacOS可执行文件格式以其“通用二进制”格式支持该格式,该格式允许单个可执行文件包含PowerPC和x86 CPU的机器代码。
不同的操作系统还使用不同的可执行文件格式,并且具有不同的支持例程。这意味着为Windows编译的程序不会在Linux上运行,即使它们都在具有相同体系结构的CPU上运行也是如此。这就是诸如Linux和WINE的Windows子系统之类的东西出现的地方,它允许一个OS加载并执行为其他OS编译的程序。
答案 1 :(得分:0)
实际上不可能为“所有体系结构”进行编译,因为其中有些与您期望的有很大差异。
我们能做的最好的事情就是编译为虚拟机字节码,例如Java或.NET。然后,编译后的代码可以在安装了虚拟机的任何系统上运行。
Java非常通用,因此是一个不错的选择。但是,由于它专注于面向对象和垃圾回收,因此为它编译C ++有点棘手。
另一个非常流行的虚拟机是JavaScript WASM(Web汇编),它以前是ASM.js,但现在更加标准化和跨浏览器。它利用了当前所有浏览器将JS编译为机器代码这一事实,因此WASM是JS的一种特殊形式,几乎可以一对一地将其编译为机器代码。
请参见https://medium.com/@tdeniffel/pragmatic-compiling-from-c-to-webassembly-a-guide-a496cc5954b8