编译链接
1.翻译环境和运行环境
在ANSI C的任何⼀种实现中,存在两个不同的环境。
- 编译环境
- 运行环境
2.翻译环境
- 翻译环境由编译和链接两个大的过程组成的,而编译又可以分解成:预处理(也叫预编译)、编译、汇编三个过程
一个项目中有多个C语言文件,那多个.c文件如何生成可执行程序呢
多个.c文件单独经过编译器,编译处理生成对应的目标文件,多个目标文件和链接库一起经过链接器处理生成最终的可执行程序
那么接下来重点讲编译过程中的三个过程
2.1 编译
译又可以分解成:预处理(也叫预编译)、编译、汇编三个过程
2.1.1 预处理(预编译)
在预编译阶段,源文件和头文件会被处理成为.i为后缀的文件
大家若有VSCode可以自己尝试(博主并没有的说)
gcc -E test.c -o test.i
2.1.2 编译
编译过程就是将预处理后的文件进行一系列的:词法分析、语法分析、语法分析及优化,生成相应的汇编代码文件。
编译过程的命令如下:
gcc -S test.i -o test.s
例子
array[index] = (index+4)*(2+6);
语法分析
词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程
词法分析
语法分析
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.语法分析程序可以用YACC等工具自动生成。
语义分析
语义分析是编译过程的一个逻辑阶段, 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查,进行类型审查。语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。比如语义分析的一个工作是进行类型审查,审查每个算符是否具有语言规范允许的运算对象,当不符合语言规范时,编译程序应报告错误。
2.1.3 汇编
汇编器是将汇编代码转转变成机器可执⾏的指令,每⼀个汇编语句⼏乎都对应⼀条机器指令。就是根据汇编指令和机器指令的对照表⼀⼀的进⾏翻译,也不做指令优化。
gcc -c test.s -o test.o
2.2 链接
链接是⼀个复杂的过程,链接的时候需要把⼀堆⽂件链接在⼀起才⽣成可执⾏程序。
链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。
链接解决的是⼀个项⽬中多⽂件、多模块之间互相调⽤的问题。
例子
在test.c文件中我们会给函数main和Add一个地址,当然我们在test.c文件中找不到Add函数,此时我们会给一个虚假的地址,然后在add.c文件中我们也会给函数Add一个地址,在链接过程中test.c文件中Add函数的地址会被替换成add.c文件中的Add函数的地址,当然这里只是浅谈,感兴趣的话大家去了解
3.运行环境
- 程序必须载⼊内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独⽴的环境中,程序的载⼊必须由⼿⼯安排,也可能是通过可执⾏代码置⼊只读内存来完成。
- 程序的执⾏便开始。接着便调⽤main函数。
- 开始执⾏程序代码。这个时候程序将使⽤⼀个运⾏时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使⽤静态(static)内存,存储于静态内存中的变量在程序的整个执⾏过程⼀直保留他们的值。
- 终⽌程序。正常终⽌main函数;也有可能是意外终⽌。