首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

程序编译与联接

2013-01-07 
程序编译与连接学习笔记,转自http://tieba.baidu.com/p/1783319407?平时做软件开发,大部分人很少关注编译

程序编译与连接

学习笔记,转自http://tieba.baidu.com/p/1783319407

?

平时做软件开发,大部分人很少关注编译和连接过程,因为所使用的集成开发环境(IDE)帮助我们做了这些事情。尤其是Linux 环境下的程序员如果不理解这些概念并使用 GNU make 来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是Linux程序员。
  IDE提供的默认配置、编译和链接参数对于大部分软件开始来说已经足够了。但其强大的功能往往会迷惑我们,很多运行机制被掩盖。当程序出现的莫名其妙 的错误、遇到性能瓶颈时,就会茫然,束手无策。因为我们只能看到问题的现象,却很难看清本质,这些问题的本质就是软件运行背后的机制,以及支持软件运行的 平台和工具。

?

下面以C语言经典入门程序“Hello World!”为例。
  #include?
  {
    printf(“Hello World!\n”);
    return 0;
  }
  我们以使用GCC来编译为例说明,此时只需要使用最简单的命令(假设源文件名为helloworld.c):
  $ gcc helloworld.c

?

事实上,上述过程分为4个步骤,分别为预处理(Preprocessing )、编译(Compilation)、汇编(Assembly)、链接(Linking)。gcc在后台实际上也经历了这几个过程,我们可以通过-v参数 查看它的编译细节,如果想看某个具体的编译过程,则可以分别使用参数-E、-S、-c和-O,对应的后台工具则分别为cpp、cc1、as、ld。

?

1、预处理
  预编译过程主要处理那些源文件中以“#”开始的预编译指令,以及删除所有的注释“//”和“/* */”。预编译过程相当于以下命令(-E表示只进行预编译):
  $ gcc -E helloworld.c -o helloworld.i
  或者
  $ cpp helloworld.c > helloworld.i

?

2、编译?
  编译工程就是把预处理完的文件进行一系列语法分析、句法分析、语义分析及优化后生成相应的汇编代码文件,这个过程往往是整个程序构建的核心部分,也是最复杂的部分之一,现在只做介绍,不再进一步分析了。编译过程相当于以下命令:
  $ gcc -S helloworld.i -o helloworld.s
  现在版本的GCC把预编译和编译合为一步,使用cc1程序完成这一过程。我们可以直接调用ccl来完成编译。
  $ ccl -S helloworld.c
  对于C语言预编译和编译程序时cc1;对于C++是cc1plus;Objective-C是cclobj;java是jc1。所以gcc命令只是这些后台程序的包装,它会根据不同的参数要求去调用不同的后台程序。
  gcc提供了一个优化选项-O,以便根据不同的运行平台和用户要求产生经过优化的汇编代码。例如,
  $ gcc helloworld.c -o helloworld  #默认优化级别(-O2)
  $ gcc -O helloworld.c -o helloworld #进行基本优化

?

3、汇编?
  汇编器将汇编代码转变成机器可以执行的指令,每一句汇编语句几乎都对已一条机器指令。所以汇编器的汇编过程相对于编译器来说比较简单,它没有复杂的语法、语义,也不需要指令优化,只要意义翻译即可,所以称为“汇编”。此过程可以使用汇编器as来完成:
  $ as helloworld.s -o helloworld.o
  或者
  $ gcc -c helloworld.s -o helloworld.o
  或者使用gcc命令从C源文件开始,经过预编译、编译、汇编后,直接输出目标文件:
  $ gcc -c helloworld.c -o helloworld.o
  gcc和as默认产生的目标代码都是ELF格式的,不再是普通的文本格式,无法直接通过文本编辑器浏览,需要一些专门的工具。

?

?


程序编译与联接

热点排行