我刚刚意识到二进制编译器会将源代码转换为目标平台的二进制文件。有点明显......但如果编译器以这种方式工作,那么同一个编译器如何用于不同的系统,如 x86、ARM、MIPS 等?
他们不应该“知道”硬件平台的机器语言才能知道如何构建二进制文件吗?编译器(如 gcc)是否知道支持的每个平台的机器语言?
该系统如何可能,以及如何同时针对这么多平台优化编译器?
我刚刚意识到二进制编译器会将源代码转换为目标平台的二进制文件。有点明显......但如果编译器以这种方式工作,那么同一个编译器如何用于不同的系统,如 x86、ARM、MIPS 等?
他们不应该“知道”硬件平台的机器语言才能知道如何构建二进制文件吗?编译器(如 gcc)是否知道支持的每个平台的机器语言?
该系统如何可能,以及如何同时针对这么多平台优化编译器?
是的,他们必须“了解”他们支持的每个平台的机器语言。这是生成机器代码所必需的。然而,编译是一个多步骤的过程。通常,编译的第一步对于大多数架构都是通用的。
取自维基百科
编译器的结构
编译器将高级语言的源程序与底层硬件连接起来。
编译器需要
确定程序语法的正确性,
生成正确有效的目标代码,
运行时组织,以及
根据汇编器和/或链接器约定格式化输出。
编译器由三个主要部分组成:前端、中间端和后端。
前端
检查程序是否根据编程语言的语法和语义正确编写。在这里可以识别合法和非法程序。以有用的方式报告错误(如果有)。类型检查也是通过收集类型信息来执行的。然后前端生成源代码的中间表示或 IR 以供中间端处理。
中间端
是优化发生的地方。用于优化的典型转换是删除无用或无法访问的代码、发现和传播常量值、将计算重新定位到执行频率较低的位置(例如,在循环之外),或基于上下文的计算的专门化。中间端为后面的后端生成另一个 IR。大多数优化工作都集中在这部分。
后端
负责将中间端的 IR 翻译成汇编代码。为每个 IR 指令选择目标指令。寄存器分配尽可能为程序变量分配处理器寄存器。后端通过弄清楚如何让并行执行单元保持忙碌、填充延迟槽等来利用硬件。尽管大多数优化算法都在 NP 中,但启发式技术已经得到了很好的发展。
http://llvm.org/项目将回答您在这方面的所有问题 :) 简而言之,交叉硬件编译器发出代码的“中间表示”,它与硬件无关,然后通过本机工具进行定制链
是的,这是可能的,它被称为Cross Compiler。编译器通常首先生成当前机器无法理解的目标代码,但可以使用另一个编译器将其迁移到目标机器。接下来,再次“编译”目标代码并与目标机器的外部库链接。
TL;DR:是的,编译器知道目标代码,但您可以在其他硬件中编译。
我建议您阅读附加的链接以获取信息。
每个平台都有自己的工具链,工具链包括gcc、gdb、ld、nm等。
让我们以现在的 gcc 为例。GCC 源代码有很多层,包括架构相关和独立的部分。体系结构相关部分包含处理体系结构特定事物的过程,例如它们的堆栈、函数调用、浮点操作。我们需要为特定架构(如 ARM)交叉编译 gcc 源代码。您可以在此处查看其步骤以供参考:- http://www.ailis.de/~k/archives/19-arm-cross-compiling-howto.html#toolchain。
这个架构相关的部分负责处理机器语言操作。