在哪些情况下生成机器代码和目标代码?

时间:2016-12-28 06:43:32

标签: assembly

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

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

    1. 编译器直接将HLL转换为LLL(机器代码/目标代码)
    2. 有人能解释两个概念,目标代码和机器代码之间的区别吗?在哪些情况下会产生这些?

1 个答案:

答案 0 :(得分:2)

不同的编译器工具链以不同的方式执行操作。正如对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的评论中所讨论的那样。我的经验主要是编写前者的编译器,但Peter Cordes正确指出GCC执行后者。除非您正在编写编译器本身,否则实际实现大多无关紧要。任何一个都会产生正确的结果,也不会对使用编译器的人产生任何相关影响。

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

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

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

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

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

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

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