- 此问题在此处已有答案**:
Does a compiler always produce an assembly code?(4个答案)
Do programming language compilers first translate to assembly or directly to machine code?(14个答案)
What do C and Assembler actually compile to? [closed](11个答案)
12小时前关门了。
如果我没记错的话,所有的编译器都有一个汇编器(ml,as等),他们用它在后台把高级代码翻译成机器语言(c/c ++代码-〉asm代码-〉机器代码)。但是我想知道现代的编译器也是这样工作的,还是把高级源代码直接编译成机器代码?所以简而言之,MSVC是在后台使用ml.exe还是GCC在后台使用./as?
2条答案
按热度按时间bnlyeluc1#
它变化。
as
程序。不是"在后台",而是作为一个单独的通道操作编译器编写的临时.s
文件。或者,如果使用-pipe
选项,则在管道中。如果使用gcc -v
编译,则可以看到运行的as
命令。as
,但是,如果你用-fno-integrated-as
关闭它,那么它将单独运行as
,你可以在clang -v
输出中看到这一点。请注意,如果编译器要支持内联asm(就像gcc和clang一样),那么它就不能很容易地完全跳过一个汇编过程,这个过程的某些阶段仍然需要知道如何将每个指令助记符汇编成机器码,在某些情况下,内联asm可能期望能够与文件中其他地方定义的asm交互,这是很难支持的,除非你有一个通道,你真正生成整个模块到汇编,或至少到一些预解析的asm等效的内部表示。
MSVC does not support inline assembly on x64,所以它不会有这个问题。事实上,这可能是不支持它的部分原因。
因此,这实际上只是一个设计决策。直接编译成机器码有一些好处:
以及外部汇编程序的一些优点:
omhiaaxx2#
照字面理解;现代编译器不需要汇编程序--直接将“最终指令表示”转换为机器码比将其转换为文本更容易、更有效。
问题是你没有看到现代的编译器,你提到的两个编译器现在都有30年的历史了(根据他们的维基百科页面,GCC和MSVC分别于1987年和1993年发布),没有人喜欢破坏兼容性的旧版本。
最著名的现代编译器可能是Clang;但它被设计成一个旧编译器的直接替代品(Clang试图支持与GCC相同的命令行参数、内联汇编语法、扩展等)。
基本上,编写现代编译器的人有3种选择:
a)破坏与古事物的兼容性,只生成机器码。
B)编写/维护更多的代码,以便能够生成机器码(作为效率的默认值),并且还能够生成汇编/文本(当通过命令行参数请求时)
c)避免破坏兼容性并避免编写/维护更多代码;并且只生成汇编/文本(尽管有潜在的效率损失)。注意,这可以包括无缝地启动外部汇编程序(可能通过.
system()
),这样用户就不需要自己处理它了。