相信大家在学习C语言时,肯定会有这么一个问题,计算机把一段程序转化为能识别的二进制机器语言的过程是什么?
大体的来讲需要经历四个过程:预处理,编译,汇编,链接。接下来我会给大家一一说明。
首先预处理过程所做的操作是 进行程序的宏替换,去注释,头文件按照路径展开,以及条件编译。
接着编译操作完成把C语言转成汇编语言。
再接下来,汇编操作完成把汇编语言转化成二进制语言(半成品)
最后,链接操作引入库文件,生成可执行的二进制代码。
为了进一步的体现这些过程,我们在linux系统下,通过指令来完成,让大家看的更明白。
首先预处理完成预替换、去注释、头文件按照路径展开、以及条件编译。
我们建立一个zuoye.c文件。里面写入注释、宏定义、头文件、条件编译。
如下图:
使用的gcc命令是:gcc –E zuoye.c -o zuoye.i
gcc -E的作用是将.c文件转化成.i文件,可以在预处理之后就停下来。
我们可以通过这条指令观察预处理以后程序的情况。
zuoye.i里包含的是预处理以后停下来的那个代码。
如下图:
此时我们发现宏定义已被替换,而注释也已经被删除,头文件展开了,条件编译也执行了。
那么接下来需要进行编译操作了。
使用的gcc命令是:gcc –S zuoye.i -o zuoye.s
gcc -S的作用是将.i文件转化成.s文件,可以在编译完成之后,汇编开始前停下来。
我们可以通过这条指令观察编译以后的情况。
zuoye.s里包含的是编译完成后,汇编开始前停下来的那个代码。
如下图:
此时我们发现,编译的这个操作已经把C语言转化为汇编语言了。
紧接着需要进行汇编操作。
使用的gcc命令是:gcc –C zuoye.s -o zuoye.o
gcc -S的作用是将.s文件转化成.o文件,可以在汇编完成后,链接开始前停下来。
我们可以通过这条指令观察汇编以后的情况。
zuoye.o里包含的是汇编完成后,链接开始前停下来的那个代码。
如下图:
通过上图,我们可以发现汇编实际上指把汇编语言代码翻译成目标机器指令的过程。
对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。
目标文件中所存放的也就是与源程序等效的目标的机器语言代码。
汇编程序生成的目标文件实际上是可重定位文件,它其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。
汇编程序生成的目标文件实际上是可重定位文件,它其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。
也就是说,由汇编程序生成的目标文件并不能立即就被执行,它并非最终可执行的二进制序列,因为其中可能还有许多没有解决的问题。那么这个就是链接程序的工作了。
所以最后为了生成可执行程序,我们需要链接。
使用的gcc命令是:gcc zuoye.o -o mytest
作用是将.o文件转化成可执行程序。
如下图:
这样就得到了计算机能够读的二进制序列了。