浅谈c程序的编译流程

原创 Jianxiong2333  2016-10-06 19:28  阅读 8,663 次

 前言

一般高级语言(如C/C++, C#, JAVA)等编译的流程:预处理(Preprocessing)-编译(compilation)-汇编(assembly)-链接(linkine)

以GCC为例:

 预处理(Preproceessing)

gcc compilation

gcc compilation

预处理是C代码变为可执行文件的第一步,主要是编译器对各种预处理代码进行处理(包括头文件包含, 宏定义拓展, 条件编译的选择)等 

 预处理的过程主要处理包括以下过程:

  • 将所有的#define删除,并且展开所有的宏定义

  • 处理所有的条件预编译指令,比如#if #ifdef #elif #else #endif等

  • 处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。

  • 删除所有注释 “//”和”/* */”.

  • 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。

  • 保留所有的#pragma编译器指令,因为编译器需要使用它们

通常使用以下命令来进行预处理:

gcc 
-E hello.c -o hello.i

参数-E表示只进行预处理
或者也可以使用以下指令完成预处理过程

cpp 
hello.c > hello.i      /*  cpp – The C Preprocessor  */

直接cat 基本名.i 你就可以看到预处理后的代码

 编译(Compilation)

编译过程就是把预处理完的文件,进行一系列的语法,词法,语义分析及优化生成后的中间语言即汇编语言(非机器语言)

编译程序工作时,先分析,后综合,从而得到目标程序。所谓分析,是指词法分析和语法分析;所谓综合是指代码优化,存储分配和代码生成。为了完成这些分析综合任务,编译程序采用对源程序进行多次扫描的办法,每次扫描集中完成一项或几项任务,也有一项任务分散到几次扫描去完成的。

此时文件名为 基本名.s

 汇编(Assembly)

汇编将中间语言(汇编)转换为机器语言(二进制码)即目标代码,每一条汇编语句都对应一条机器码(特殊除外)汇编过程较为简单 根据汇编指令和机器指令按对照表翻译即可

此时文件名为 基本名.o //文件内容为机器码 不能以普通文本形式查看(显示乱码)

 链接(Linking)

通过调用链接器ld来链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件。(目标文件, 库代码, 启动代码)

ld
-static crt1.o crti.o crtbeginT.o hello.o -start-group -lgcc -lgcc_eh
-lc-end-group crtend.o crtn.o (省略了文件的路径名)。

链接的主要内容是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接。

链接的主要过程包括:

地址和空间分配(Address
and Storage Allocation)

符号决议(Symbol Resolution),

重定位(Relocation){把它们的各种符号引用和符号定义转换为可执行文件中的合适信息(一般是虚拟内存地址)的过程。}等。

链接分为静态链接和动态链接。

  • 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大。

  • 而动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。

静态链接的大致过程如下图所示:

static linking

 

static linking

编译过程可分为6步:扫描(词法分析)、语法分析、语义分析、源代码优化、代码生成、目标代码优化。

  • 词法分析:扫描器(Scanner)将源代的字符序列分割成一系列的记号(Token)。lex工具可实现词法扫描。

  • 语法分析:语法分析器将记号(Token)产生语法树(Syntax
    Tree)。yacc工具可实现语法分析(yacc: Yet Another Compiler Compiler)。

  • 语义分析:静态语义(在编译器可以确定的语义)、动态语义(只能在运行期才能确定的语义)。

  • 源代码优化:源代码优化器(Source
    Code Optimizer),将整个语法书转化为中间代码(Intermediate
    Code)(中间代码是与目标机器和运行环境无关的)。中间代码使得编译器被分为前端和后端。编译器前端负责产生机器无关的中间代码;编译器后端将中间代码转化为目标机器代码。

  • 目标代码生成:代码生成器(Code
    Generator).

  • 目标代码优化:目标代码优化器(Target
    Code Optimizer)。

 

 

 

参考资料:

[1]《程序员的自我修养——链接、装载与库》

http://www.stackpop.org/blog/html/y2011/53_cpp_compile_linking.html

http://blog.chinaunix.net/space.php?uid=20196318&do=blog&id=28797

[2]C程序编译过程浅谈

[3]GCC_COMPILATION_STAGES/STATIC LINKING

[4]编译原理 (预处理>编译>汇编>链接)

 

本文地址:http://www.gouliguo.com/qiantancbianyi/
版权声明:本文为原创文章,版权归 Jianxiong2333 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

  1. Get More Info
    Get More Info 【农民】 @回复

    Everything said made a great deal of sense. However, what about this?
    what if you added a little information? I ain’t suggesting your
    content isn’t good, however suppose you added something to maybe
    get a person’s attention? I mean 浅谈c程序的编译流程|苟利国 is a
    little plain. You ought to peek at Yahoo’s front page and
    note how they create post headlines to get viewers to open the
    links. You might add a video or a picture or two to
    get readers excited about what you’ve written. In my opinion,
    it might bring your posts a little livelier.

  2. powerwashing Monroe NJ
    powerwashing Monroe NJ 【农民】 @回复

    Thanks for sharing your thoughts about c语言. Regards

  3. Landscape Blogs
    Landscape Blogs 【农民】 @回复

    I believe what you typed was actually very logical. But, what
    about this? suppose you were to write a killer post title?
    I mean, I don’t wish to tell you how to run your website, however what if you added something to possibly
    get folk’s attention? I mean 浅谈c程序的编译流程|苟利国 is kinda plain. You ought
    to look at Yahoo’s front page and see how they create article titles to grab people to open the links.

    You might try adding a video or a related picture or two
    to get readers excited about what you’ve written. In my opinion, it could bring your website a little livelier.