01makefile学习之GCC编译的四个阶段(带编译阶段、汇编阶段、-S,-c的区别)
以下为相关makefile的学习文章
01makefile学习之GCC编译的四个阶段(带编译阶段、汇编阶段、-S,-c的区别)
02makefile学习之makefile的基本原则
03makefile学习之makefile的一个规则
04makefile学习之多个规则处理多个文件
05makefile学习之两个函数和一个特殊规则clean
06makefile学习之三个自动变量(@ , @,@,^,$<)和模式规则
07makefile学习之习题1
08makefile学习之习题2
1 Linux下GCC编译器编译C语言的四个过程
1)预处理阶段(-E);
2)编译阶段(-S);
3)汇编阶段(-c);
4)链接阶段(-O);
2 分析各个阶段主要处理的工作内容
1)预处理阶段:主要对include,define这些预处理命令进行处理。通过使用命令-E可以让gcc编译器只进行预处理而不往下执行。
2)编译阶段:主要是对我们写的代码转成汇编代码,后缀为.s。通过使用命令-S可以让gcc编译器转成汇编代码后立马停止往后执行。注:预处理也会经过的,因为不进行预处理无法到达编译阶段。
3)汇编阶段:将上面保存汇编代码的.s文件转成.o的目标文件(二进制代码)并进行汇编。通过使用命令小写-c可以让gcc编译器只经历编译阶段并且在汇编阶段只生成目标代码而不进行汇编。注意汇编代码是在汇编阶段前生成。
4)链接阶段:将上面的.o目标文件链接形成可执行文件。
通过使用命令-o可以让gcc编译器直接生成可执行文件。
3 重点!!!!!!
1)重点1(编译阶段、汇编阶段、-S,-c的区别):此篇重点之重点,对于理解编译和汇编阶段,-S,-c选项的要点。
首先我们先明确一点:要生成某些文件,并不一定要经历或者经历完那个阶段。例如下面;
-S:代表进行到编译阶段生成汇编代码后立马停止往后执行,前面的预编译也会执行。此时有可能未完全经历编译阶段。对比-c生成目标代码后但会继续往后执行,但会跳过。
-c:代表在编译阶段只编译并且在汇编阶段只生成目标代码而不进行(即跳过)汇编步骤(汇编阶段的一些工作)。所以我们可以看出,在汇编阶段生成目标代码不需要进行汇编也是可以的,它们是分割的。即汇编阶段是一个公司,汇编步骤是由一个人负责管理;生成目标代码则由另一个人管理,-c就代表只叫负责管理生成目标代码的人工作。管理汇编的那个人不需要做。
该重点对于我们理解上面编译和汇编两个阶段是非常重要的,它将阶段的信息和命令组合一起理解。
上面重点这么多的话实际上简短总结就是:
-S :在编译阶段将代码转成汇编代码,并且前面的阶段都会经历。
-c:不执行前面的阶段,只在编译阶段编译并且在汇编阶段生成目标文件后跳过汇编和链接。所以很多人短说:只编译不汇编链接(但会在汇编阶段生成目标文件)
2)重点2:有很多人以为-o是生成可执行文件,而实际上-o的作用只是可以认为指定生成的文件名,并无实际作用。
例如:
gcc -c hello.c -o hello //-c代表只生成目标代码.o文件而跳过汇编和链接(但是平时很多程序员都默认叫他只编译而不汇编),并不是真正的可执行文件,所以它没有权限执行.所以到这里懂了吧?若-o是生成执行文件,那么hello必定可以执行,但实际上我试过确实是不行的。
//有人问,那么下面这句为什么可以执行生成可执行文件呢?
gcc hello.c -o hello
//原因:gcc编译当你不加选项时,默认生成可执行文件
3)图形理解-S,-c的区别:
-S:
-c:
对比两个可以知道,-S真的只有调试信息,根本就不支持命令,说明它根本就没往后执行生成目标代码。
而-c生成了目标代码并且是可以接受命令的,但是缺少了汇编和链接导致某些信息不存在而没有权限执行。
但我后面又尝试多次执行-S,不一定会出现-S时的图片情况,而是同样出现没权限,具体是因为什么就不得而知了,这里主要方便大家理解即可。
4 总结
最后我们总结一下,我们在实际项目的应用理解中,我们只需要知道过程的四个阶段和-S,-c的作用即可;每个阶段做的事情和用哪个命令经历它不需要记住,因为它们很容易混淆,并且我在写这篇文章时,看了一些书作参考,都是写得非常矛盾的。