编译过程略述

一.程序从编写到运行经历了四个过程(预处理,编译,汇编,链接)
①预处理
 gcc -E hello.c -o hello.i
 
 1.将所有的“define”删除,并且展开所用的宏定义。
 2.处理所用的条件编译指令,比如“#if”、“#ifdef”、“#elif”、“#else”、“#endif”。
 3.处理“#define”预处理命令,将包含的文件插入到该预处理指令的位置。这个过程是递归的,
 也就是说包含的文件可能还包含其他文件。
 4.删除所有的注释 “//‘和“/**/"
 5.添加行号和文件名标识,比如#2“hello.c” 2. 以便编译器产生调试用的行号信息以及用于
 编译时产生编译错误或者警告时能够显示行号。
 6.保留所有的#pragma编译指令,因为编译器需要用它们。
 
 
②编译
 1.把预处理完的文件一系列语法分析、词法分析、语义分析以及优化产生的汇编文件,
 
 gcc -S hello.i -o hello.s
③汇编
 1.汇编器是将汇编代码转化为机器可执行的指令,每一个汇编语句几乎都应一条机器指令。没有语义,没有优化
 as hello.s -o hello.o
④链接
 ld
 1.将所需要的库与目标文件链接形成最终的可执行程序
 经过汇编器所汇编形成的目标文件已经非常接近最后的目标代码了,毕竟可执行文件、目标文件、
动态链接库和静态链接库采用的是相同的PE格式。只是说目标文件中有些地址没有进行重定向。
这里不得不说一下动态链接库和静态链接库,dll是PE格式,其既内容可以调用lib,又可以调用其他的dll.
在vs2017中可以产生dll,在其他源文件中要调用它时,可以LoadLibrary("xxx.dll")进行调用
https://www.cnblogs.com/woshitianma/p/3681745.html
静态链接库可以被看作是被编译但是没有被链接的函数集合,其是要在链接时与目标文件融合,而dll时被动态的加载的,是在程序运行
过程中,加载到内存中供多个应用程序进行使用(share objects,linux上为so)。这就可以大大的节约内存,由于这个特性,
在程序中常常被设计为插件,在需要的时候加载入内存,不需要的时候卸载。
 

 

posted on 2019-03-30 23:08  年少小五郎  阅读(137)  评论(0编辑  收藏  举报

导航