编译器是否与操作系统相关?

7

我理解编译器的作用是将源代码编译成计算机可以理解的机器码。但是,我想知道的是,这个机器码是否针对每个不同的操作系统而有所不同?在Mac、Windows和Linux操作系统上,为了同一种语言是否需要编写不同的编译器呢?请详细阐述答案是否定的、肯定的或介于两者之间。

3个回答

8
这要看情况而定。
生成机器指令的编译器是与特定“机器”(或“架构”)相关的:ARM和x86有不同的指令集,因此机器代码对于每种架构都会非常不同,但这并不一定依赖于操作系统(尽管通常如此,因为不同的操作系统具有不同的调用约定等)。链接器组件几乎总是特定于操作系统,因为这是为该操作系统创建可执行文件的过程。并非所有编译器系统都将编译器与链接器分开 - 如果它是一个程序,则它将是特定于操作系统的。
然而,也有针对操作系统/机器无关的编译器:最著名的是Java(以及其他基于JVM的语言,如Scala或Groovy)。这是因为Java编译器为JVM生成字节码,并由Java运行时执行(这是特定于操作系统和处理器的)。但是Java编译器(编写在Java中)可以在任何计算机上运行,并生成可在任何计算机上运行的代码。

谢谢你的回答。这让我想到了另一个困惑的领域,就是关于JVM的。在第二部分中,你所说的跨平台是否意味着为不同的操作系统编写不同的编译器?我很困惑,因为你说Java编译器是跨平台的,但是又说Java编译器可以在任何机器上运行。总的来说,我对JVM感到很困惑 - 在整个过程中哪些步骤是与操作系统相关的,哪些可以在任何计算机上运行? - user8768055
@user8768055。在高级语言中编写的没有使用任何输入或输出的函数或过程的简单程序可能会被编译器翻译成特定于给定计算机体系结构(无论操作系统)的机器代码。现在,在高级语言中编写的使用任何I/O或具有函数或过程的程序,也将被翻译为特定于给定计算机体系结构的机器代码,并且将考虑到提供支持+功能的给定操作系统转换I/O操作和调用例程。 - Victor

1
编译输出包含两个部分: 1. 调用操作系统库例程 2. 执行“业务逻辑”的本机机器码
第二部分很可能对于针对特定处理器架构的每次编译都是相同的(如果您使用相同版本的GCC,为什么不是呢)。
库例程的调用是问题所在。这就是Linux上存在WINE的原因——它提供了一些在Linux上运行的“模拟”/“翻译”的例程,以便让您在外星操作系统上运行Windows程序。
所以答案实际上不完全是“是”或“否”,而是“不完全是”。

-1

请记住,运行在一个操作系统上的编译器可以为另一个操作系统生成代码。

因此,如果我为操作系统A编写编译器,并且它可以为操作系统B生成核心,则我可以编译为A编写的编译器,但输出为B。然后我就有了一个针对B的编译器。从技术上讲,有些人可能不会称其为同一编译器。


请注意,上述描述的东西被称为“交叉编译器”。 - Victor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接