我们都知道,计算机只能读懂二进制数序列,而我们平常所书写的代码是如何让计算机读懂,然后进行执行的呢?
从一个代码到可执行程序可分为四步:预处理、编译、汇编、链接
如何实现这四个步骤呢?
预处理:gcc -E hello.c -o hello.i
编译:gcc -S hello.i -o hello.s
汇编:gcc -c hello.s -o hello.o
链接生成可执行文件:gcc hello.o -o hello
在这里我着重说一下在gcc命令下的选项的含义:
-E:仅作预处理,不进行编译、汇编和链接
-S:仅编译到汇编语言,不进行汇编和链接
-c:编译、汇编到目标代码(也就是计算机可识别的二进制)
-o:执行命令后文件的命名
-g:生成调试信息
-w:不生成任何警告
-Wall:生成所有的警告
接下来我们尝试着实践一下:
首先我们先创建一个hello.c文件
接着对这个hello.c进行预处理、编译、汇编
我们发现此时生成了三个文件分别为:hello.i、hello.s、hello.o这三个文件分别是预处理、编译、汇编后的文件,让我们用cat命令来看看在不同的情况下,文件里面的内容究竟是什么?
首先看看hello.i
接着是hello.s
最后是hello.o
这时候我们发现,在三个文件中他们的内容大相径庭,在hello.i文件中,可以看到我们所写代码的大致主体,并且这个时候将头文件展开,也就是预处理阶段所进行的操作,而hello.s中,是汇编语言,将我们的代码编译成汇编语言,最后一个hello.o就是计算机所能认识的序列,这个时候在进行最后一步:gcc hello.o -o hello就可以进行链接,生成我们的可执行文件hello,最后用./来执行这个hello
这里我们就完成了从最开始的代码,到最终可执行文件的整个过程。最后我们再来看看这个阶段所生成的hello.i、hello.s、hello.o都是什么类型的。
这里可以看到,我们hello.i是一个C文本文件,hello.s是一个汇编文本文件,hello.o是一个可重定位文件,而最后的hello则是可执行文件。
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!