gcc相关

什么是GCC

GCC (GNU Compiler Collection,GNU编译套件),包括了一些语言的前端和库

c++编译过程

image-20230111104033382

在 C++ 中编译过程分为四个阶段:预处理、编译、汇编、链接

  • 预处理阶段主要负责宏定义的替换、条件编译、将 include 的头文件展开到正文等;
  • 编译阶段负责将源代码转为汇编代码;
  • 汇编阶段负责将汇编代码转为可重定位的目标二进制文件;
  • 链接阶段负责将所有的目标文件(二进制目标文件、库文件等)连接起来,进行符号解析和重定位,最后生成可执行文件

预处理

使用命令 -E 进行预处理, -o test.i 表示要生成的目标文件名为 test.i

1
g++ test.cpp -E -o test.i

eg:

编写以下代码, 使用上述命令

image-20230111111920711

打开生成的.i文件

前面为头文件的展开

image-20230111111951578

宏定义PI被换成了3.14, 注释也不见了

image-20230111112015179

删除注释 ( 准确的说是用空格代替注释 )

展开并删除宏定义 #define

处理所有的预编译指令

处理#include预编译指令, 将被包含的文件插入到预编译指令的位置

添加行号信息, 文件名标识, 便于调试

保留#pragma编译指令

生成.i文件

编译

编译阶段负责将高级语言转为汇编代码

使用 -s 命令, 得到 .s 文件

1
g++ test.i -S -o test.s

eg :

使用上述命令后, 查看.s文件

image-20230111112035453

扫描, 语法分析, 语义分析, 源代码分析, 目标代码生成, 目标代码优化

生成汇编代码

汇总符号

生成.s文件

汇编

汇编到二进制文件的过程

使用 -s 命令, 得到 .o 文件

1
g++ test.s -s -o test.o

eg:

执行上述代码, 得到二进制文件

image-20230111112143053

由汇编指令到二进制

合并section, 合并符号表

生成.o文件

链接

1
g++ test.o -o test 

合并各个.obj文件的section, 合并符号集, 进行符号解析

符号地址重定位

生成可执行文件

gcc常用参数选项

image-20230111113322525 image-20230111115751273

关于 -D 命令的解释

image-20230111114123179

-D选项可以指定一个宏, 后面可以跟一个空格, 也可以不跟

gcc和g++

image-20230111112645706 image-20230111112932818