早上好啊,大伙。这个专栏的内容基本就是做笔记,只是给我自己和大伙再学习之后如果忘记哪些内容可以很快的来查看,还是建议大伙去看汪辰老师的视频,老师讲的还是很好的。

文章目录
GCC
GCC简介
由 GNU开发的,遵循 GPL许可证发行的编译器套件。
GCC(GNU Compiler Collection)是Linux系统中最著名的开源编译器套件,支持C、C++、Objective-C、Fortran、Ada等多种编程语言。这个始于1987年的编译器项目,如今已成为开发者构建项目的核心工具链。
为什么说GCC是程序员的必备工具?
跨平台支持:可在Windows/Mac/Linux等系统使用
高度优化:支持-O1到-O3多级代码优化
灵活扩展:可搭配Makefile实现自动化构建
调试友好:生成带调试信息的可执行文件
GCC命令格式
c
gcc [ options ] [ filenames ]
常用选项 | 含义 |
---|---|
-E | 只做预处理 |
-c | 只编译不链接,生成目标文件".o" |
-S | 生成汇编代码 |
-o file | 把输出生成到由 file 指定文件名的文件中 |
-g | 在输出的文件中加入支持调试的信息 |
-v | 显示输出详细的命令执行过程信息 |
GCC的主要执行步骤
-
编译
编译器完成"预处理"和"编译"'预处理"指处理源文件中以"#"开头的预处理指令,譬如 #include、#define 等"编译" 则针对预处理的结果进行一系列的词法分析、请语法分析、语义分析,优化后生成汇编指令,存放在 .o 为后缀的目标文件中。
-
汇编(as)
汇编器将汇编语言代码转换为机器(CPU)可以执行的指令。
-
链接(ld)
链接器将汇编器生成的目标文件和一些标准库(譬如 libc)文件组合,形成最终可执行的应用程序。

我们这里写一个 .c 文件,然后让它编译一下,给大伙看看它的运行经历了哪些事情。
就写一个梦的开始来做样例吧~
在前面说过gcc 加上选项 -v 就能返回执行过程。
bash
gcc hello.c -v
如果大家是第一次使用gcc这个指令,它会说没有这个指令,大家按照它的提示安装一下就行了。

解析一下它的执行流程
预处理和编译,这里就是生成的一个.s的临时文件。
然后再把这个.s的临时文件,执行as指令,生成一个包含机器码的.o文件。
最后,它会调用collect2,它会引用很多文件,才能生成最后的可执行文件。
GCC涉及的文件类型
后缀 | 文件类型 |
---|---|
.c:C | 源文件 |
.cc/.cxx/.cpp | C++ 源文件 |
.i | 经过预处理的C 源文件 |
.s/.S | 汇编语言源文件 |
.h | 头(header)文件 |
.o | 目标(object)文件 |
.a/.so | 编译后的静态库(archive)文件和共享(shared object)文件 |
a.out | 可执行文件 |
ELF
ELF简介
ELF(Executable and Linkable Format)是Linux系统的标准二进制文件格式,堪称可执行文件的"DNA"。无论是我们编译生成的a.out,还是系统级的glibc.so,甚至是内核模块.ko文件,都采用这种统一的文件结构。
ELF的三重身份:
可执行文件:可以直接运行的独立程序
共享目标文件:.so动态链接库
可重定位文件:.o中间目标文件
ELF 文件类型 | 说明 | 实例 |
---|---|---|
可重定位文件(Relocatable File) | 内容包含了代码和数据,可以被链接成可执行文件或共享目标文件。 | Linux 上的 .o文件 |
可执行文件(Executable File) | 可以直接执行的程序 | Linux 上的a.out |
共享目标文件(Shared Object File) | 内容包含了代码和数据,可以作为链接器的输入,在链接阶段和其他的 Relocatable File或者 Shared Object File一起链接成新的 Obiect File;或者在运行阶段,作为动态链接器的输入,和 Executable File 结合,作为进程的一部分来运行 | Linux 上的 .so |
核心转储文件(Core Dump File) | 进程意外终止时,系统可以将该进程的部分内容和终止时的其他状态信息保存到该文件中以供调试分析 | Linux上的core 文件 |
文件格式

文件头(ELF Header)
使用readelf -h查看文件头信息,包含以下关键字段:
字段 | 说明 | 典型值示例 |
---|---|---|
Magic Number | 文件标识(7F 45 4C 46) | 7F 45 4C 46 |
Class | 32/64位架构 | ELF64 |
Type | 文件类型(EXEC/DYN/REL) | DYN (Position-Independent Executable) |
Entry point address | 程序入口地址 | 0x400520 |
Start of program headers | 程序头表偏移 | 64 |
Start of section headers | 节头表偏移 | 13912 |
核心数据段
程序头表(Program Header Table)
- 描述段(Segment)信息,用于程序执行
- 查看命令:readelf -l
段类型 | 作用说明 |
---|---|
LOAD | 需要加载到内存的段 |
DYNAMIC | 动态链接信息 |
INTERP | 指定动态链接器路径 |
节头表(Section Header Table)
- 描述节(Section)信息,用于链接和调试
- 查看命令:readelf -S
关键节 | 功能说明 |
---|---|
.text | 代码段(机器指令) |
.data | 已初始化的全局变量 |
.bss | 未初始化的全局变量 |
.rodata | 只读数据(字符串常量等) |
.symtab | 符号表 |
.strtab | 字符串表 |
动态链接相关结构
- .dynamic段:记录依赖的共享库
- .got(全局偏移表):支持位置无关代码
- .plt(过程链接表):实现延迟绑定
bash
# 查看动态段信息
readelf -d /usr/bin/ls
# 输出示例:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
文件处理相关工具:Binutils
网址:Binutils
ar:归档文件,将多个文件打包成一个大文件。
as:被 gcc 调用,输入汇编文件,输出目标文件供链接器 ld 连接。
ld:GNU 链接器。被 gcc 调用,它把目标文件和各种库文件结合在一起,重定位数据,并链接符号引用。
objcopy:执行文件格式转换。
objdump:显示 ELF 文件的信息
readelf:显示更多 ELF 格式文件的信息(包DWARF 调试信息)
例如说下面用 readelf 命令查看头 ------
感谢大伙观看,别忘了三连支持一下
大家也可以关注一下我的其它专栏,同样精彩喔~
下期见咯~
