C语言编译链接详解
目录
(一)编译环境和运行环境
(二)编译的具体流程
(三)链接中的重定位
(四)运行环境
我们知道用C语言写出的代码并不能直接运行,得通过编译链接生成可执行程序。而我们今天要讲的就是C语言从源代码到预处理再到编译等等直至生成可执行程序的过程。
(一)编译环境和运行环境
一张图来表示出编译环境和运行环境。
(二)编译的具体流程
编译又可以分为三个过程,也就是预处理(也有说法叫预编译),编译,汇编。预处理是主要处理#开头的代码。具体包括1.把#difine删去并把定义的宏展开到源代码去。2.如果展开的宏中仍包括宏,则进行把这定义的宏展开,直到检测到没有宏为止。3.把包含的头文件包括到源文件中。4.添加行数和文件名标识,方便后面调试。5.预处理条件编译。6.删去所有的注释。7.保留所有的#pragma,留着后面使用。预处理之后就是编译了。编译可以分成词法分析,语法分析,语义分析及优化。将源代码程序被输⼊扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成⼀系列 的记号(关键字、标识符、字⾯量、特殊字符等)。比如int arr[20];会被词法分析器分析成int,arr,[,20,],;。词法分析完之后会交给语法分析,语法分析器生成一个语法树然后再交给语义分析。语义分析就会根据语法树检测是否有语法错误发生。静态语义分析通常包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息。再接下来就是汇编了,它把汇编代码翻译成由二进制构成的机械指令。最后就是链接了。链接是⼀个复杂的过程,链接的时候需要把⼀堆⽂件链接在⼀起才⽣成可执⾏程序。 链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。 链接解决的是⼀个项⽬中多⽂件、多模块之间互相调⽤的问题。
(三)链接中的重定位
由于编译文件是一个一个编译的并不是同时进行。在编译一个文件的时候,计算机并不知道其他文件。如果一个文件的代码需要使用到其他文件,这个时候就需要重定位了。当一个文件使用到其他文件的代码时,先搁置这个代码,然后等编译这个代码所在的文件的时候,再把真正的地址给算进去。
(四)运行环境
程序必须载⼊内存中。1.在有操作系统的环境中:⼀般这个由操作系统完成。在独⽴的环境中,程序的载⼊必须由⼿⼯安排,也可能是通过可执⾏代码置⼊只读内存来完成。 2. 程序的执⾏便开始。接着便调⽤main函数。3. 开始执⾏程序代码。这个时候程序将使⽤⼀个运⾏时堆栈(stack),存储函数的局部变量和返回 地址。程序同时也可以使⽤静态(static)内存,存储于静态内存中的变量在程序的整个执⾏过程 ⼀直保留他们的值。 4. 终⽌程序。正常终⽌main函数;也有可能是意外终⽌。