目录
1、程序的编译环境和执行环境
2、编译环境
预处理:
编译环节:
汇编:
链接:
3、程序执行环境
1、程序的编译环境和执行环境
如图所示,我如果有一个test.c的文件,经过了编译环境之后,就会生成一个test.exe(windows系统下为.exe;Linux系统下为.out)文件,然后进入执行环境,将生成的.exe文件执行。
比较笼统的讲法:
一个test.c的文件经过编译环境之后产生一个test.exe.文件。再在执行环境中去执行二进制的指令。
2、编译环境
每一个源文件都会经过编译器单独处理,生成一个目标文件。(如图)
生成的所有的目标文件合在一起,加上链接库,经过链接器的处理,会生成一个可执行程序。
我们可以把编译环境再细分为编译和链接。
在windows环境下,一个文件.c的经过经过编译,会生成一个.obj的文件。比如:
这些.obj文件就是文件经过编译产生的。
当多个.obj这样的目标文件+链接库,经过链接器链接,产生了一个.exe文件。
在vs中,编译器用的是一个叫cl.exe的文件,链接器用的是一个叫link.exe的文件。
如图,编译实际上还分为预处理和编译和汇编。
预处理:
①展开头文件
②删除注释
③宏替换
都是些文本替换
将所有的预处理指令全部都进行替换
我们在Linux环境下演示,
目前,我们让gcc去编译我们的test.c文件,然后写入test.i中
样弄完之后,会发现都顶上有一堆代码,而这些就是stdio.h里面的内容
编译环节:
gcc -S ,生成一个.s的文件
作用:就是把C语言的代码翻译生成汇编代码。
干了这样几件事情:
词法分析。比如int main()是什么,什么意思,将每个小单词分离开来等等;
语法分析:将分开的小的段连接起来;
语义分析:对应着什么汇编代码,读懂代码(注意这里的读懂不是指逻辑上的读懂)
符号汇总:将C中所有的全局变量的名称汇总起来;注意,这里是在每一个目标文件中单独汇总的 (如上图)
汇编:
生成一个test.o的文件
——机器的二进制指令->汇编指令生成二进制指令;
并形成符号表
链接:
顾名思义,就是将每个文件连接在一起。主要是符号表的、段位的合并。
每个目标文件会有多个段,那么将每个文件的相同的段位合并,符号表也会被合并。
3、程序执行环境
程序必须载入内存中。
在有操作系统的环境中:一般这个由操作系统完成。
在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码植入只读内存来完成。
程序的执行便开始。接着便调用main函数。
#include <stdio.h> int main() { int i = 0; for(i=0; i<10; i++) { printf("%d ", i); } return 0; }
这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
终止程序。正常终止main函数;也有可能是意外终止。
笼统的讲:载入内存->调用main()->运行程序,创建函数运行时堆栈等->程序运行结束
本节内容还是比较少的,到此为止,我们C语言的相关部分就全部结束了。