gcc与gdb
gcc编译一个文件经过以下几个步骤
一.预编译
详细的代码如:gcc -E xxx.c -o xxx.i;
1.处理文件中 “#”开头的行
a.头文件包含命令
把后面的头文件内容在此展开
比如:#include<xxx.h>和#include"xxx.h"这时候会问:<> ""有什么区别?
搜索路径的不同:<>会到标准的头文件目录去查询 如:/usr/inlcude
"" 先到当前工作目录搜索,没有的话再到标准的头文件目录去找
b.define的宏定义
对于本文中的宏定义全部替换;省去了函数调用的开销,但是会加大内存的开销
c.条件编译
处理头文件中条件编译的相关内容如:#ifndef #define #endif
二.编译
把C程序汇编成汇编程序:gcc -S xxx.i -o xxx.s
找“编译”的过程当中,就是将预处理完的文件进行一系列的 词法分析、语法分析 以及生成相应地汇编文件。如果你的代码有语法问题,编译器会报错。
三.汇编
把汇编程序编译成一个目标文件(机器指令文件)此时,一条汇编语句将会对应唯一的一条机器码,机器码文件一般都是.o后缀如 gcc -c xxx.s -o xxx.o(就是把一个汇编文件编译成含有机器指令的文件)
"目标文件":(linux/unix)有一个专门的格式 ELF(Executable and Linkable Format)
"linux下面内存布局":
分段:
.text
只存放指令部分
这个段的属性:
只读
随程序持续性
.data
存放已经初始化的全局变量和已经初始化的static变量
这个段的属性:
可读可写
随程序持续性
.bss
存放没有初始化的全局变量和没有初始化的static变量
这个段的属性:
可读可写
随程序持续性
.rodata
只读数据段
堆区
存放malloc或者new产生的数据
栈区
......
四.链接
把各个.o 文件链接成一个可执行文件