【问题标题】:How can a compiler be cross platform(hardware)?编译器如何跨平台(硬件)?
【发布时间】:2024-05-04 14:10:03
【问题描述】:

我刚刚意识到二进制编译器会将源代码转换为目标平台的二进制文件。有点明显......但是如果编译器以这种方式工作,那么同一个编译器如何用于不同的系统,如 x86、ARM、MIPS 等?

他们不应该“知道”硬件平台的机器语言才能知道如何构建二进制文件吗?编译器(如 gcc)是否知道所支持的每个平台的机器语言?

该系统是如何实现的?如何同时针对这么多平台优化编译器?

【问题讨论】:

  • “编译器(如 gcc)是否知道所支持的每个平台的机器语言?”单一版本的 GCC 不会,因为它将针对特定的 CPU 系列。但是 GCC 源代码树中存在对所有这些平台的支持,因此您可以为每个目标构建 GCC 版本。

标签: gcc compiler-construction compilation cross-platform


【解决方案1】:

是的,他们必须“了解”他们支持的每个平台的机器语言。这是生成机器代码所必需的。然而,编译是一个多步骤的过程。通常,编译的第一步对大多数架构都是通用的。

取自*

编译器的结构

编译器在高层桥接源程序 带有底层硬件的语言。

编译器需要

  1. 判断程序语法的正确性,

  2. 生成正确高效的目标代码,

  3. 运行时组织和

  4. 根据汇编器和/或链接器约定格式化输出。

一个 编译器由三个主要部分组成:前端、中端、 和后端。

前端

检查程序是否正确 根据编程语言的语法和语义编写。 在这里可以识别合法和非法程序。报错, 如果有的话,以一种有用的方式。类型检查也是通过收集来执行的 类型信息。然后前端生成一个中间 用于处理的源代码的表示或 IR 中端。

中间端

是进行优化的地方。典型的 优化转换是删除无用或无法访问的 代码,常量值的发现和传播,重定位 计算到执行频率较低的地方(例如,在循环之外), 或基于上下文的计算专业化。中端 为以下后端生成另一个 IR。大多数优化 努力集中在这部分。

后端

负责将IR从中间端翻译成汇编代码。目标 为每个 IR 指令选择指令。寄存器分配 尽可能为程序变量分配处理器寄存器。 后端通过弄清楚如何保持并行来利用硬件 执行单元忙,填充延迟槽,等等。虽然大多数 优化算法在 NP 中,启发式技术在 发达。

更多描述structure of a compiler的文章和处理Cross compilers的文章。

【讨论】:

    【解决方案2】:

    http://llvm.org/ 项目将回答您在这方面的所有问题 :) 简而言之,跨硬件编译器发出代码的“中间表示”,它与硬件无关,然后通过 native 工具链进行定制

    【讨论】:

      【解决方案3】:

      是的,它被称为Cross Compiler。编译器通常首先生成object code,当前机器无法理解,但可以使用另一个编译器将其迁移到命运机器。接下来,目标代码被再次“编译”并与目标机器的外部库链接。

      TL;DR:是的,编译器知道目标代码,但您可以在其他硬件中编译。

      我建议您阅读附加链接以获取信息。

      【讨论】:

        【解决方案4】:

        每个平台都有自己的工具链,工具链包括gcc、gdb、ld、nm等

        让我们以 gcc 为例。 GCC 源代码有很多层,包括架构相关和独立的部分。体系结构相关部分包含处理体系结构特定事物的过程,例如它们的堆栈、函数调用、浮点操作。我们需要为特定架构(如 ARM)交叉编译 gcc 源代码。您可以在此处查看其步骤以供参考:-http://www.ailis.de/~k/archives/19-arm-cross-compiling-howto.html#toolchain

        这个依赖于架构的部分负责处理机器语言操作。

        【讨论】: