写在前面
本文主要介绍Linux
下gcc
编译的知识
gcc
gcc介绍
gcc
最开始的时候是 GNU C Compiler
, 如你所知,就是一个c
编译器。但是后来因为这个项目里边集成了更多其他不同语言的编译器,所以表示一堆编译器的合集。 g++
则是GCC
的c++
编译器。
现在你在编译代码时调用的gcc
,已经不是当初那个c
语言编译器了。更确切的说他是一个驱动程序,根据代码的后缀名来判断调用c
编译器还是c++
编译器 g++
。比如你的代码后缀是.c
,他会调用c
编译器还有linker
去链接c
的library
。如果你的代码后缀是.cpp
, 他会调用g++
编译器,当然library call
也是c++
版本的。当然我说了这么多你可能感到有些混乱,没关系,你就把gcc当成c语言编译器,g当成c语言编译器用就是了。
安装
sudo apt-get install g++
g++ --version
判断是否安装成功
gcc编译的四个步骤
gcc编译程序可分为四个步骤:预处理 --> 编译 --> 汇编 --> 链接
gcc常用参数
-I
:指定头文件所在的目录-c
:只做预处理、编译、汇编,得到二进制文件-g
:编译时添加调试语句,主要用于gdb
调试Wall
:显示所有警告信息- '-D':向程序中动态注册宏定义
- '-O':
数据段合并
图例解释:
.text
:存放程序运行代码(机器码).rodata
:只读数据段.data
:存放了经过初始化的全局变量和静态变量.bss
:保存了那些用到但未被初始化的数据
地址回填
在代码内调用自己的函数有一个统一的地址,在程序未执行时 main
函数地址为0
,假设代码如下
#include<stdio.h>
void fun1(){
}
void fun2(){
}
int main(){
fun1();
fun2();
}
在程序未执行时,代码中的函数都是没有地址的,fun1
与fun2
函数的地址为main
函数的地址加上一个数值,也就是,代码中剩余的函数地址是基于main
的,地址为main地址 + x
,当程序开始执行时,内存会分给main
函数确切的地址,此时会把原来代替的地址回填到main地址 + x
中,该过程为地址回填。