C 语⾔执⾏过程
以简单的C程序来较深⼊的理解⼀下C程序是如何从源代码到最后的可执⾏程序的(对于⾮计算机专业的同学理解C语⾔,以及计算机也有很好的帮助)
⾸先是⼤家在课本上都看过的,先从整体上来看⼀下(以⼀个简单的源程序hello.c为例):
hello.c----预处理器---->hello.i----编译器---->hello.s----汇编器---->hello.o----链接器---->hello(可执⾏程序)
好了很枯燥,也很抽象,接下来我们具体来看⼀看。
下⾯是实例代码:
我们⽤记事本来创建源⽂件:
如果是windows系统的话,就是直接在记事本⾥⾯编写,保存时选择所有⽂件,并命名为hello.c(我这⾥是Linux系统)
这样我们就得到了⼀个⽤⾼级语⾔编写的源⽂件,也是⼤部分同学学习的重点
⼤家都知道源⽂件是易于我们理解的,接近⾃然语⾔,但是计算机并不认识它,所有要想运⾏程序必须将其转换成可执⾏的⼆进制⽂件,就是⼀堆01序列
接下来就是预处理器的⼯作了,预处理器根将系统头⽂件插⼊程序⽂本中,也就是上⾯程序中的stdio.h,得到另⼀个C程序,通常是以.i为⽂件拓展名
stdio.h当中定义了⼀些运⾏程序所需要的⼀些常量和函数
之后编译器将⽂本⽂件hello.i翻译成⽂本⽂件hello.s,它包含⼀个汇编语⾔程序
通过在Linux终端运⾏命令,可以得到汇编语⾔程序(虽然操作系统给我们的感觉是⿏标的点击和⼀系列动作在完成运⾏程序,但是我们要知道这背后其实是⼀条条命令的执⾏)
linux> gcc -S hello.c
在windows的命令⾏窗⼝可以执⾏同样的操作
这⾏命令中,gcc是调⽤编译器,⼤部分的时候我们⽤到的都是它,⽐如在codeblocks等集成的IDE中,都是与其相似的编译器#include <stdio.h>int main () { printf ("hello\n"); return 0;}
1
2
3
4
5
6
-S指明⽣成汇编程序
我们得到了hello.s
c语言编译器ide代码编辑这些看不懂的东西就是确确实实在发⽣的,要理解这个⽂件还需要更多的知识,这不是我们现在的重点
接下来就是汇编阶段,汇编器将hello.s翻译成及其语⾔指令,把这些指令打包成⼀种可重定位⽬标程序的格式,并将结果保存在⽬标⽂件hello.o中,⼀个⼆进制⽂件,如果⽤⽂本编辑器打开,我们会得到⼀堆乱码(如果在编写代码时,不⼩⼼把main()打成mian()就会,报错不到xxx.o)
同样执⾏命令
linux> gcc -c hello.c
-c指明让gcc去编译并汇编该代码
如果要查看机器代码⽂件,我们需要反汇编器,这些程序根据机器代码产⽣⼀种类似于汇编代码的格式
linux> objdump -d hello.o
左边是以⼗六进制数表⽰的机器指令,右边是对应的汇编代码
那么经过汇编器得到的⼆进制⽂件是不是就是我们的可执⾏程序呢?
答案是我们还需要经过链接,因为库函数还没有被我们导⼊
hello程序调⽤了printf函数,它是每个C编译器都提供的标准C库中的⼀个函数,printf函数存在于⼀个名为printf.o的单独的预编译好的⽬标⽂件中,这个⽂件必须以某种⽅式合并到我们的hello.o程序中,合并后我们就得到了⼀个可执⾏⽬标⽂件,可以加载到内存中,由系统执⾏
linux> gcc -o hello hello.c
执⾏这个命令,编译器就会帮我们⼲完所有的事情,直接从源⽂件到可执⾏⽂件
图中的hello就是Linux系统下的⼀个可执⾏⽂件
终端执⾏命令:
linux> ./hello
可以看到程序执⾏了,输出了字符,然后终⽌。
好了从⼀个简单的⽂件我们了解了C程序的形成过程,希望⽐⼤家在课堂上听到的更加直观!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论