【问题标题】:Under which cases are machine code and object code generated?在哪些情况下会生成机器码和目标码?
【发布时间】:2016-12-28 06:43:32
【问题描述】:

经过this,我知道可能有两种情况:

  1. 编译器将 HLL 转换为汇编语言,然后汇编器将汇编语言转换为 LL 语言(机器代码/目标代码)

  1. 编译器直接将 HLL 转换为 LLL(机器码/目标码)

谁能解释一下目标代码和机器代码这两个概念之间的区别?这些是在什么情况下生成的?

【问题讨论】:

  • 它们是同义词。尽管“目标代码”意味着它是像 ELF 这样的目标文件格式,而不仅仅是位于内存中的裸机代码(例如,由 JIT 编译器生成)。

标签: assembly


【解决方案1】:

不同的编译器工具链做不同的事情。正如在 your original questionsome compilers convert source code directly into machine codeothers convert source code into assembly code (which serves as an intermediate representation), and then run that assembly code through an assembler to generate machine code 的 cmets 中所讨论的。我的经验主要是使用执行前者的编译器,但 Peter Cordes 正确地指出 GCC 执行后者。除非您正在处理编译器本身,否则实际的实现几乎是无关紧要的。任何一个都会产生正确的结果,并且对使用编译器的人没有任何相关影响。

实际上还有另一种替代方案,在概念上介于这两个模型之间。 Clang(更具体地说,LLVM)就是一个例子。它将源代码编译成一种中间语言,但不是使用特定于体系结构的汇编语言作为中间表示,而是使用 IR(中间表示)。事实上,this is the big innovation of the LLVM compilation model。工具链分三个阶段实现:有一个将源代码解析为 IR 代码的 frontend,一个对 IR 代码执行优化传递的 optimizer,然后是一个 >后端将 IR 代码转换为特定 CPU 的机器代码。

这种设计允许为各种源语言编写各种前端,以及针对任何 CPU 的各种后端。然而,位于中间的优化器在所有情况下都是相同的,因为它适用于始终相同的中间 IR 代码。

其他编译器可能会在内部执行类似的操作(以便从外部显示为单个步骤),或者它们可能直接编译为特定于体系结构的机器代码。

至于你的具体问题,“目标代码”和“机器代码”有什么区别,真的没有区别。目标代码通常是指您在目标文件中找到的内容,例如 *nix 上的 ELF 或 Windows 上的 PE,但这实际上只是机器代码。

顾名思义,机器代码是特定于机器的。 x86 的机器代码只能在 x86 处理器上运行; ARM 机器码只在 ARM 处理器上运行;等等

这是由编译器作为输出的最后阶段生成的。它生成一个目标文件,其中包含目标代码,实际上只是打包到目标文件中的机器代码。然而,目标文件通常不仅仅包含机器代码——它们还包含用于内部和外部符号、常量数据、调试信息等的表。所有这些都由 链接器 在生成最终文件时使用来自这些目标文件的可执行映像。

虽然您没有具体询问,但汇编代码只是机器代码的人类可读形式。机器码是可以直接由处理器执行的二进制格式,而汇编代码使用的助记符更便于程序员读写。例如,在 x86 上,目标代码可能包含字节 0x74,但在汇编语言中,这将由助记符 JE(或等效的 JZ)表示。汇编程序是将汇编语言助记符转换为二进制机器码的程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-25
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多