[笔记一]探究编译与链接

来源:互联网 发布:淘宝放心淘加权重吗 编辑:程序博客网 时间:2024/06/07 02:46

探究编译与链接

选择程序员入门程序来当门神(hello.c)

#include<stdio.h>int main(){    printf("Hello World\n");    return 0;}

被隐藏了的过程

我们使用gcc编译一个程序,只需使用一个命令,例如编译程序 hello.c

$gcc hello.c

会生成一个可执行文件 a.out, 运行即可

$./a.outHello World

然其过程可以分解成以下4个步骤:

  • 预处理(prepressing)
  • 编译(compilation)
  • 汇编(assembly)
  • 链接(linking)
    Gcc编译过程分解

预编译

预编译命令(-E表示只进行预编译):

$gcc -E hello.c -o hello.i

or

$cpp hello.c > hello.i

命令处理完成之后你会发现 hello.i 文件非常之大,你如果知晓这步干了些啥,也就不足为奇了。

本职工作主要是处理源码文件中的以“#”开始的预编译指令,如“#include”、“#define”等,规则如下:

  • 去除所有的“#define”,展开所有的宏定义
  • 处理所有的条件预编译指令(“#if”、“#ifdef“、“#elif”、“#else”、“#endif”)
  • 递归处理”#include”指令,将被包含的文件插入到该预编译指令的位置
  • 删除所有的注释(“//”、“/* */”)
  • 添加文件名标识和行号,便于调试
  • 保留所有的 #pragma 编译器指令,因为后面编译器需要使用它们

编译

编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。

$gcc -S hello.i -o hello.s

上面的命令可以得到汇编输出文件hello.s。对于c语言的代码来说,这个预编译和编译的程序是cc1,对于C++来说,对应的程序是cc1plus;Object-c是cc1obj; Java是jc1。故实际上gcc这个命令只是这些后台程序的包装,根据不同的参数要求去调用预编译程序cc1、汇编器as、连接器ld

汇编

汇编器是将汇编代码转变成机器可以执行的指令。

$as hello.s -o hello.o

or

$gcc -c hello.s -o hello.o

or

$gcc -c hello.c -o hello.o

链接

链接过程主要包括了地址和空间分配(Address and Storage Allocation)符号决议(Symbol Resolution)重定位(Relocation)等这些步骤。

$ld -static crt1.o crti.o crtbeginT.o hello.o -start-group -lgcc -lgcc_eh -lc -end-group crtend.o crtn.o

Happy Writing!

0 0
原创粉丝点击