【问题标题】:Some questions regarding compilers and assemblers关于编译器和汇编器的一些问题
【发布时间】:2012-10-26 05:09:07
【问题描述】:

我的脑海中有很多基本问题。我需要清除它们。

声明 1: 编译器将人类可读的代码转换为目标代码,然后通过链接器将这些代码转换为机器代码(可执行文件)。

我在这里吗?

wikipedia 上写着

Object files are produced by an assembler, compiler, or other language
translator, and used as input to the linker.

问题 1: 汇编程序将汇编语言代码 (MOV A, BADD C) 转换为机器代码。对于像 C++ 这样的高级语言,它是由上面的链接器生成的。所以汇编程序不在任何地方使用。那么它如何创建一个上面写的目标文件呢?

生成中间代码,使代码在不同的架构上运行。

问题 2: *.class(字节码)文件是由 java 编译器目标文件创建的吗?如果是,那么我们可以说运行它们的 JVM 是一种链接器(但它不会创建可执行文件)?

问题 3: 当我们在 Turbo C++ 中编译 C++ 程序时,我们会得到 *.obj 文件,它们是目标文件。我们可以使用它们在其他架构中生成可执行文件吗?

【问题讨论】:

  • 烦人:正如你所说,这些不是“怀疑”,而是问题。
  • 你是对的!标题已更改。
  • 不太对。编译器将一种语言 A(不一定是“可读”)转换为一种语言 B,它可以比源语言更“可读”或更不“可读”。

标签: assembly compiler-construction machine-code object-code


【解决方案1】:

目标文件是“机器码”(.text)、初始化数据和符号的集合,它们将被链接

一个有效的目标文件可以只包含数据,例如字节码。

链接器是将一大堆对象映射到虚拟地址空间并解析某些外部符号属于哪个地址的程序。这允许程序的增量开发,因为一个人只需要在调用时知道一个接口,例如函数 printf。链接器将在链接阶段将 printf 的真实地址注入机器代码中。这是通过重定位表完成的。

这部分回答了问题 #3:不能直接使用由另一种架构创建的目标文件。接口方法不一定是二进制兼容的。 obj 文件格式也可以不同。但是,如果真的付出努力,可以编写包装器(很可能在汇编中),它可以从 Visual C 调用在 Turbo C 中编译的对象。如果指令集和内存模型等完全不同,仍然可以编写一个仿真器来调用功能。这些方法在写作时经常使用,例如视频播放框架,可以调用一些仅在.dll中提供的传统视频解码器。

当操作系统将可执行文件从磁盘加载到内存或程序与“动态库”链接时,链接也会部分发生。在这些情况下,可以向“printf”注入许多调用,但链接器只调用“存根”,一旦被调用,就会从操作系统加载正确的库并用库函数替换自己。

声明#1 不够正确。编译器和汇编器将人类可读的代码转换为机器代码,尽管一些编译器会生成要解释的中间语言(和/或“及时”编译)。在这最后阶段,编译真正意味着它应该做的——编译成机器代码。

Gcc 包含一个汇编器和链接器。可以将int main() { printf("HelloW\n");}gcc -S hw.c 编译成汇编程序(hw.s),这是符号机器代码,插入或替换一些行并重新编译为目标代码gcc -c hw.s,最后链接gcc -o hw.exe hw.o

【讨论】:

    【解决方案2】:

    问题 1:是的,汇编程序(as、gas、nasm、masm)将汇编指令编译为目标代码。在高级语言 (H) 的情况下,编译器将 H 编译为另一种语言(例如 GHC,Glorious Haskell 编译器可以生成 C,但它也可以生成 C--,并且尝试(?)生成Java),或通过中间步骤(或语言 C-- 或 Core)转换为目标代码。

    生成中间代码的原因有很多: 1. 可移植性,例如来自 java 的 .class 文件,Pascal 的 p 代码 2.便于代码优化

    问题 2:java 编译器可以生成 .class 文件,但 Scala 也生成 .class 文件,而 AspectJ(面向方面​​的风格)也生成 .class 文件。 .class 文件不是目标文件,因为它们需要 Java 虚拟机(并且 unix 链接器 ld 不会将 .class 文件链接到 .o 文件)。原始 JVM 是 .class 文件的解释器,但您也可以即时编译 java。

    问题 3:Turbo C++ .obj 文件(在 64 位 intel 上编译)在 Z80 机器上不会令人满意,除非编译器可以选择交叉编译另一个架构,所以对于 Turbo C++,目的是目标文件不能跨平台移植。

    【讨论】:

    • 维基百科上写着汇编程序可以生成目标文件。我认为编译器正在这样做。汇编程序只是将汇编语言转换为机器代码。不是吗?
    • 汇编器只是一个从人类可读语言到目标文件的编译器(另一种人类不太可读的语言),但它是一种非常原始的语言:它没有做太多。
    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 2010-10-09
    相关资源
    最近更新 更多