`
xitongyunwei
  • 浏览: 929656 次
文章分类
社区版块
存档分类
最新评论

C++笔记(1): 预处理/编译/汇编/链接

 
阅读更多

使用g++编译c/c++程序时,假设程序无错,我们通常直接使用以下命令:

?
001
g++ hello.cpp

这样系统会自动生成默认可执行文件a.out.

或者使用

?
001
g++ -o hello hello.cpp

则会生成一个可执行文件hello.

同时我相信很多人使用Visual C++时候,都是直接点击Run或者Debug,然后去看返回的错误,至于是哪个过程出错了,有很多人根本没有试过去搞明白,他们习惯去折腾代码本身而对编译器做了什么一无所知,我认为这样的编程习惯是糟糕的,即使你是VC或者其它IDE使用者,不需要自行编写makefile文件,也应当搞清楚自己所写的程序是如何的一个编译过程.




上图中这一命令虽然简单,实际上却包含了数个过程,这里我们不像讲解编译原理一样去分析C++程序的编译过程,在这里我们可以分解为四个步骤:

  • 预处理(Prepressing)
  • 编译(compilation)
  • 汇编(Assembly)
  • 链接(Linking)

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

  • 将所有的#define删除,并且展开所有的宏定义
  • 处理所有的条件预编译指令,比如#if #ifdef #elif #else #endif等
  • 处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。
  • 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
  • 保留所有的#pragma编译器指令,因为编译器需要使用它们

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

?
001
g++ -E hello.c -o hello.i

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

cpp hello.c > hello.i

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

二. 编译的过程

就是把预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码.

使用以下命令进行编译:

?
001
g++ -S hello.i -o hello.s

编译后的程序hello.s是一个汇编语言的程序,你可以打开看看里面的内容是各种类似于mov,sub之类的汇编指令.

三 . 汇编的过程

则是将汇编代码转换成机器可以执行的指令,我们通过调用汇编器as来完成

?
001
as hello.s -o hello.o

或者使用以下命令也行,g++会自动调用as程序

?
001
g++ -c hello.s -o hello.o

汇编将输出一个目标文件hello.o

四.链接的过程

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


在这里顺便讲一下静态链接动态链接的概念。静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大.而动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去.

本文只是很粗略地介绍了一下这个过程,之后也会就每个环节深入的研究,文章中若有不妥之处,还敬请留言指出.


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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics