一个C程序是如何运行的

程序的编译过程

我们知道 ,我们写好的程序是不能直接运行的,计算机只能识别二进制代码,也就是说我们写的程序有一个从高级语言转化到机器语言的一个过程,今天我们具体的讨论一下这个过程

编译

想要运行程序,第一步便是编译 编译的整体过程 1,预处理

a)宏替换
b)去掉注释
c)条件编译~~~
d)替换头文件

预处理是一个整体的过程,我们举例 如下图下面是源代码在这里插入图片描述在linux中,使用gcc编译器我们可以分步编译,我们首先让gcc实现预处理编译部分(gcc -E main.c -o main.i),得到结果如下图在这里插入图片描述我们发现,一个几行的代码变成了842行,这是因为预处理过程中的替换头文件起了作用,将头文件替换成了相应的代码,我们再仔细对比源代码,发现源代码中的SIZE变成5,这也就是我们的宏替换.(在这里提一点这里的预处理将一个只有几行的代码变成了800多行的代码,这大大降低了程序的编译速度,vs提供的解决方案是预编译,也就像缓存的形式解决这一问题,没有真正从源头上解决这一问题.但在2020年的c++20后会根本解决这一问题,因为c++20中引入了模块这一特性)
2,编译(c语言源代码文件变成汇编代码)
gcc -S main.i -o main.s ,汇编代码是很接近机器码的代码,它会根据不同的cpu代码也有所不同在这里插入图片描述mov指令是不是很熟悉呢

3,汇编(汇编代码转化为机器码)
在这里插入图片描述gcc -C main.s -o main.o
到这里我们对我们来说可读性降低,对机器来说可读性在一步一步上升,当然还是不能直接运行,因为需要后边的步骤

链接

为什么要进行链接呢,因为我们写的程序往往不只需要我们所写的这几行代码,我们还需要头文件中的函数,比如printf函数,所以我们要通过链接器把程序链接起来, gcc main.o -o hello ![是](https://img-blog.csdnimg.cn/2019020113412537.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMDE2NDYy,size_16,color_FFFFFF,t_70) 链接后,这个程序就可以执行了,但其实这里还有一步我们没有察觉 那就是

装入

装入哪里呢,其实就是装入到内存,这一步通常由操作系统来完成,把程序装入相应的代码段,堆栈段等等,最终程序就能运行起来了

猜你喜欢

转载自blog.csdn.net/qq_41016462/article/details/86739623