我知道这是一个非常基本的问题,但是当我用gcc/g编译我的c/c代码时,在汇编器开始生成机器码之前,中间输出的类型到底是什么?是不是像X86指令?
fzsnzjdm1#
GCC的处理链如下:1.您的源代码1.预处理源代码(扩展宏和包含、删除注解)(-E,.ii)1.编译为程序集(-S,.s)1.汇编为二进制(-c,.o)1.链接到可执行文件在每个阶段,我都列出了使进程停止的相关编译器标志,以及相应的文件后缀。如果您使用-flto编译,那么目标文件将使用GIMPLE字节码进行修饰,这是一种低级中间格式,其目的是将实际的最终编译延迟到链接阶段,从而实现链接时优化。“编译”阶段是真正的重部件。预处理器本质上是一个分离的、独立的工具(尽管它的行为是由C和C++标准规定的),而汇编器和链接器实际上是分离的、独立的工具,它们基本上只是分别实现硬件的二进制指令格式和操作系统的可加载可执行格式。
-E
.ii
-S
.s
-c
.o
-flto
vaj7vani2#
因此,GCC中可执行文件的编译包括4个部分:1.)预处理(gcc -E main. c〉main.i;将 *.c转换为 *.i)包含扩展,处理marcos。删除注解。2.)编译(gcc-S main.i;将 *.i转换为 *.s,如果成功)将C代码编译为汇编程序(在目标x86体系结构上,它是x86汇编程序,在目标x86_64体系结构上,它是x64汇编程序,在目标arm体系结构上,它是arm汇编程序,等等)大多数警告和错误都在此部分发生(例如,执行错误和警告报告)3.)汇编(作为main.s -o main.o;将 *.i转换为 *.o,如果成功的话再转换一次)汇编程序生成的汇编程序转换为机器码。2尽管还有过程的相对地址等等。4.)链接(gcc main.o)将相对地址替换为绝对地址。删除无用的文本。在此阶段链接错误和警告。最后(如果成功),我们得到可执行文件。所以,为了回答你的问题,你所指的中间输出实际上就是所谓的汇编语言--参见关于Assembly language wiki的wiki。
sbtkgmzw3#
下面是gcc编译步骤的图形表示,由redhat magazine提供:
与其他答案所暗示的相反,这里没有汇编步骤--相反,生成汇编程序代码代替了生成目标代码;如果您真正需要是二进制表示,那么将内存中的表示转换为文本表示就没有多大意义。
4smxwvx54#
必须是汇编代码,您可以在命令行中使用-S标志来获取,以便编译
9rnv2umw5#
没有“中间输出”。你得到的第一个输出是机器码。(尽管你可以通过用-E调用 *only * 预处理器来得到C/C++中间输出。)
7eumitmz6#
GCC工具链,将程序从源代码编译成机器码。编译器生成汇编代码,汇编器将其汇编成机器码。Here是初学者的好教程。
6条答案
按热度按时间fzsnzjdm1#
GCC的处理链如下:
1.您的源代码
1.预处理源代码(扩展宏和包含、删除注解)(
-E
,.ii
)1.编译为程序集(
-S
,.s
)1.汇编为二进制(
-c
,.o
)1.链接到可执行文件
在每个阶段,我都列出了使进程停止的相关编译器标志,以及相应的文件后缀。
如果您使用
-flto
编译,那么目标文件将使用GIMPLE字节码进行修饰,这是一种低级中间格式,其目的是将实际的最终编译延迟到链接阶段,从而实现链接时优化。“编译”阶段是真正的重部件。预处理器本质上是一个分离的、独立的工具(尽管它的行为是由C和C++标准规定的),而汇编器和链接器实际上是分离的、独立的工具,它们基本上只是分别实现硬件的二进制指令格式和操作系统的可加载可执行格式。
vaj7vani2#
因此,GCC中可执行文件的编译包括4个部分:
1.)预处理(gcc -E main. c〉main.i;将 *.c转换为 *.i)包含扩展,处理marcos。删除注解。
2.)编译(gcc-S main.i;将 *.i转换为 *.s,如果成功)将C代码编译为汇编程序(在目标x86体系结构上,它是x86汇编程序,在目标x86_64体系结构上,它是x64汇编程序,在目标arm体系结构上,它是arm汇编程序,等等)大多数警告和错误都在此部分发生(例如,执行错误和警告报告)
3.)汇编(作为main.s -o main.o;将 *.i转换为 *.o,如果成功的话再转换一次)汇编程序生成的汇编程序转换为机器码。2尽管还有过程的相对地址等等。
4.)链接(gcc main.o)将相对地址替换为绝对地址。删除无用的文本。在此阶段链接错误和警告。最后(如果成功),我们得到可执行文件。
所以,为了回答你的问题,你所指的中间输出实际上就是所谓的汇编语言--参见关于Assembly language wiki的wiki。
sbtkgmzw3#
下面是gcc编译步骤的图形表示,由redhat magazine提供:
与其他答案所暗示的相反,这里没有汇编步骤--相反,生成汇编程序代码代替了生成目标代码;如果您真正需要是二进制表示,那么将内存中的表示转换为文本表示就没有多大意义。
4smxwvx54#
必须是汇编代码,您可以在命令行中使用
-S
标志来获取,以便编译9rnv2umw5#
没有“中间输出”。你得到的第一个输出是机器码。(尽管你可以通过用
-E
调用 *only * 预处理器来得到C/C++中间输出。)7eumitmz6#
GCC工具链,将程序从源代码编译成机器码。编译器生成汇编代码,汇编器将其汇编成机器码。Here是初学者的好教程。