gcc - 编译器是否真的产生机器码?

标签 gcc compilation programming-languages cpu machine-code

我一直在阅读,在大多数情况下(如 gcc),编译器会以高级语言读取源代码并输出相应的机器代码。现在,根据定义,机器代码是处理器可以直接理解的代码。因此,机器代码应该只依赖于机器(处理器)并且独立于操作系统。但这种情况并非如此。即使 2 个不同的操作系统在同一个处理器上运行,我也无法在这两个操作系统上运行相同的编译文件(Windows 为 .exe 或 Linux 为 .out)。

那么,我错过了什么? gcc 编译器(和大多数编译器)的输出不是机器代码吗?或者机器代码不是最低级别的代码,操作系统将其进一步翻译成一组处理器可以执行的指令?

最佳答案

您混淆了一些事情。我像 gcc 这样的可重定向编译器和其他通用编译器将文件编译为对象,然后链接器稍后根据需要将对象与其他库链接以生成所谓的二进制文件,然后操作系统可以读取、解析、加载可加载 block 并开始执行。

一个理智的编译器作者会使用汇编语言作为编译器的输出,然后编译器或他们的 makefile 中的用户调用创建对象的汇编器。这就是 gcc 的工作原理。以及 clang 的工作原理,但 llc 现在可以直接制作对象,而不仅仅是组装的组装。

生成生成原始机器代码的可调试汇编语言更有意义。您确实需要像 JIT 这样的充分理由来跳过该步骤。我会避免直接使用机器代码的工具链,因为它们可以,它们更难维护,更有可能出现错误或修复错误需要更长的时间。

如果架构相同,则没有理由不能让通用工具链为不兼容的操作系统生成代码。例如,gnu 工具可以做到这一点。操作系统差异不是机器代码级别的定义,大多数是高级语言级别的 C 库,您可以创建 gui 窗口等与机器代码或处理器体系结构无关,对于某些操作系统相同操作系统特定的 C 代码可以在 mips 或 arm 或 powerpc 或 x86 上使用。架构变得具体的地方是调用实际系统调用的机制。经常使用特定的指令。机器代码最终会被使用,但没有理由不能在实际或内联汇编中编码。

然后这会导致库,即使是通用 C 调用的 fopen 和 printf 最终也必须进行系统调用,所以很多库支持代码可以跨系统兼容高级语言,需要有一个最后一英里的系统和架构特定代码。您应该在 glibc 源代码中看到这一点,或者在其他库解决方案中与 newlib Hook 。作为例子。

对于 C++ 等其他语言和 C 语言也是如此。解释型语言有额外的层,但它们的虚拟机只是位于相似层上的程序。

低级编程并不意味着机器或汇编语言,它只是意味着您使用的任何编程语言都可以在较低级别访问,在应用程序之下或在操作系统之下等......

关于gcc - 编译器是否真的产生机器码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52901266/

相关文章:

javascript - 为什么 [1, 2, , 4, 5] 是一个有效的 JavaScript 数组?

java - 选择一种语言来编写技术工程数学(我可以使用 Java 吗?)

windows - 创建脚本语言

linux - 从 linux 交叉编译到 ARM-ELF (ARM926EJ-S/MT7108)

python - 编译一个 .pyw 文件,这样它就可以在没有控制台的情况下像 .pyc 一样运行

java - 在JDBC中运行教程示例时出错:UnsupportedClassVersionError

c - 为什么static和register存储类不能一起使用呢?

gcc - 包含所有 GCC 错误和警告消息的网页?

c++ - 静态库中的符号有时会链接到可执行文件中,有时不会

c++ - 我可以让 GCC 在将太宽的类型传递给函数时发出警告吗?