【问题标题】:How does the C++ compiler know which CPU architecture is being usedC++ 编译器如何知道正在使用哪种 CPU 架构
【发布时间】:2017-03-10 10:04:06
【问题描述】:

参考:http://www.cplusplus.com/articles/2v07M4Gy/

在编译阶段,

此阶段将程序转换为低级汇编级代码。编译器采用预处理文件(没有任何指令)并生成一个包含汇编级代码的目标文件。现在,创建的目标文件是二进制形式。在创建的目标文件中,每一行描述一个低级机器级指令。

现在,如果我是正确的,那么不同的 CPU 架构适用于不同的汇编语言/语法。

我的问题是编译器如何知道源代码必须更改为哪种汇编语言语法?换句话说,C++ 编译器如何知道它正在运行的机器中的 CPU 架构是什么?

汇编器是否使用任何与 CPU 架构相关的映射来为不同的 CPU 架构生成汇编代码?

NS:我是初学者!!

【问题讨论】:

  • 因为编译器本身已经构建为针对显式目标体系结构?或者如果它支持多种架构,它知道本机架构并将其用作默认架构?
  • “架构”这个名字已经清楚地表明,除了不同的汇编语言之外,还有更多的差异。
  • 除非您使用所谓的“交叉编译器”,否则大多数编译器都会为它们运行的​​操作系统编写代码

标签: c++ assembly


【解决方案1】:

每个编译器都需要“移植”到给定的系统。对于每个支持的系统,都需要由深入了解系统的人编写“编译器端口”。

【讨论】:

  • 好的。知道了。谢谢。那么,当我们下载 dev C++ 或 turbo C++ 安装文件(适用于 windows)时,会发生这种情况。
  • @user7689322 Dev C++ 使用 gcc 编译器的 Windows 端口,称为“Mingw”。 Turbo C++ 是一个非标准的 MS DOS 编译器,它不能在 Windows 上运行,因为它是为 DOS 编写的。在 Windows 上使用它的唯一方法是通过模拟器运行它。
  • 呃,Dev-C++ 和 Turbo C++ 已经过时了。有更新更好的免费 C++ 环境可用。 (代码::块,QtCreator,Eclipse CDT,...)。无论如何,答案是 Dev-C++ 的设置文件包括 MinGW32 GCC 编译器,这是一个 GCC 版本,被配置为生成适用于运行 Windows 的 x86 芯片的代码。
  • @SebastianRedl 我不会称 Eclipse 比什么都好。我在 Turbo C++ 和 Dev C++(很久以前)中都完成了项目,在这些项目中我很高效并且专注于对应用程序进行编程,而不是配置和调试 IDE。因此,Turbo C++ 和 Dev C++ IDE:s 优于 Eclipse,Codeblocks、QtCreator、notepad.exe...
  • @Lundin 但至少 Eclipse CDT 支持现代编译器,不像 Dev-C++。
【解决方案2】:

警告:这是非常简化的

简而言之,编译器包含三个主要部分:

  • “前端”:这部分读取语言(在本例中为 c++)并将其转换为一种特定于编译器的伪代码。 (抽象句法树,或 AST)

  • "Optimizer/Middle-end" : 这部分采用 AST 并进行非架构依赖的优化。

  • “后端”:这部分采用 AST,并将其转换为二进制可执行代码,特定于您要在其上编译语言的架构。

当您为您的平台下载 c++ 编译器时,实际上是在下载带有 linux-amd64 后端的 c++ 前端。

这种编码架构非常有用,因为它允许将编译器移植到另一个架构,而无需重写整个解析/优化的东西。它还允许人们创建另一个优化器,甚至是另一个支持完全不同语言的前端,并且只要它输出正确的 AST,它将与为该编译器编写的每个后端兼容。

【讨论】:

    【解决方案3】:

    简单来说,就是将目标系统的知识编码到编译器中。

    因此,您可能有一个生成 SPARC 二进制文件的 C 编译器和一个生成 VAX 二进制文件的 C 编译器。它们都接受相同的输入语言(如 C 标准中定义的那样),但从中生成不同的程序。

    我们通常只提到“ 编译器”,意思是为我们当前环境生成二进制文件的那个。

    在现代,编译器集合(如 GCC)的区别已经变得不那么明显了。现在“不同的编译器”往往是同一个编译程序,只是设置了不同的配置(这些是“目标描述文件”)。

    【讨论】:

      【解决方案4】:

      只是为了完成这里给出的答案:

      目标架构确实已编码到您正在使用的特定编译器实例中。这对于称为“交叉编译”的过程也很重要 - 在某个系统上编译将在另一个系统/架构上运行的可执行文件的过程。

      考虑使用与您自己的指令集完全不同的嵌入式片上系统 - 您正在使用 x86/64 Linux 系统,但需要编译在 ARM 微处理器上运行的移动应用,或某种其他类型的程序集架构。 在目标系统上编译代码是不合理的,这可能在 CPU 和内存方面非常有限,以至于无法运行编译器 - 因此您可以为该目标体系结构使用 GCC(或任何其他编译器)端口在您最喜欢的系统上。

      记住整个工具链通常与目标系统兼容也很重要,例如当 libc 等共享库开始发挥作用时 - 因为目标操作系统可能是 Linux 的不同版本,并且会具有不同版本的常用函数 - 在这种情况下,通常使用包含所有必要库的工具链,并使用 chrootmock 之类的东西在系统内的“目标环境”中编译。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        相关资源
        最近更新 更多