当前位置:  开发笔记 > 编程语言 > 正文

编程语言编译器首先转换为汇编还是直接转换为机器代码?

如何解决《编程语言编译器首先转换为汇编还是直接转换为机器代码?》经验,为你挑选了5个好方法。

我主要对流行的和广泛使用的编译器感兴趣,比如gcc.但如果不同的编译器对事情做了不同的事情,我也想知道.

以gcc为例,它是否将用C编写的简短程序直接编译为机器代码,或者首先将其转换为人类可读的汇编,然后才使用(内置?)汇编程序将汇编程序转换为二进制,机器代码 - CPU的一系列指令?

使用汇编代码创建二进制可执行文件是一项非常昂贵的操作吗?或者这是一个相对简单快速的事情?

(假设我们只处理x86系列处理器,所有程序都是为Linux编写的.)

我对此事的任何帮助和想法都非常感激.谢谢!



1> 小智..:

gcc实际上生成汇编程序并使用as汇编程序汇编它.并非所有编译器都这样做 - MS编译器直接生成目标代码,但您可以使它们生成汇编程序输出.将汇编程序转换为目标代码是一个非常简单的过程,至少与编译相比.

一些编译器生成其他高级语言代码作为其输出 - 例如,cfront,第一个C++编译器生成C作为其输出,然后由C编译器编译.

请注意,直接编译或汇编实际上都不会生成可执行文件.这是由链接器完成的,它接受编译/汇编产生的各种目标代码文件,解析它们包含的所有名称并生成最终的可执行二进制文件.


一些历史编译器用于直接生成可执行文件.有些人甚至可以在编译期间一次性编写一个可执行的.COM文件[按照每个过程的代码,编译器可以输出该过程中的补丁点列表以及前一个过程的补丁点列表的地址; 启动代码可以在加载代码时制作所有必要的补丁.这使得即使在使用软盘时也可以在非常小的内存空间中进行快速编译.

2> Norman Ramse..:

几乎所有编译器(包括gcc)都会生成汇编代码,因为它更容易 - 生成和调试编译器.主要的例外情况通常是即时编译器或交互式编译器,其作者不希望性能开销或分支整个进程运行汇编程序的麻烦.一些有趣的例子包括

新泽西州的标准ML,它以交互方式运行并动态编译每个表达.

该tinycc编译器,它被设计成足够快的编译,下载,并在远低于100毫秒运行C脚本,因此不希望调用汇编程序和连接的开销.

这些案例的共同点是对"瞬时"反应的渴望.汇编程序和链接器速度很快,但不足以进行交互式响应.然而.

还有一大类语言,例如Smalltalk,Java和Lua,它们编译为字节码,而不是汇编代码,但是它的实现稍后可以将该字节码直接转换为机器代码,而无需汇编程序的好处.

(脚注:在20世纪90年代早期,Mary Fernandez和我编写了新泽西机器代码工具包,其代码在线,它生成C库,编译器编写者可以使用它来绕过标准汇编器和链接器.Mary使用它大致加倍生成时优化链接器的速度a.out.如果你不写入磁盘,速度会更快......)



3> Asaf R..:

通常,编译器将源代码解析为抽象语法树(AST),然后解析为某种中间语言.只有这样,通常在一些优化之后,它们才会发出目标语言.

关于gcc,它可以编译到各种各样的目标.我不知道对于x86它是否首先编译成汇编,但我确实给了你一些关于编译器的见解 - 你也问过这个问题.



4> Bill the Liz..:

根据第二章的介绍逆向工程软件(由Mike Perry和Nasko Oskov),GCC和cl.exe时(后端编译器MSVC++)已在-S开关,您可以使用输出每个编译器生成的程序集.

您还可以在详细模式(gcc -v)中运行gcc 以获取它执行的命令列表,以查看它在幕后执行的操作.



5> Zifre..:

GCC编译成汇编程序.其他一些编译器则没有.例如,LLVM-GCC编译为LLVM-assembly或LLVM-bytecode,然后将其编译为机器代码.几乎所有编译器都有某种内部表示,LLVM-GCC使用LLVM,而IIRC,GCC使用称为GIMPLE的东西.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有