编译链接流程与底层细节

个人主页 : 流年如夢

专栏 : 《C语言》

因为要用到 gcc 编译环境,作者本人目前还不会🥹,相关截图没有,可以先大概了解一下,后面学习了会补充完整,请谅解🙏🙏🙏,感谢支持。

文章目录

Ladies and gentlemen,本篇文章讲的是 翻译环境、运行环境、预处理、编译、汇编、链接 全过程,是理解程序底层运行、解决多文件编译问题;全程高能,不容错过!!!

前言

我们写的.c源代码,无法直接被计算机执行,必须经过一系列翻译步骤,变成可执行程序。这个过程就是编译+链接 。理解编译与链接,能帮助大家搞懂头文件重复包含、宏展开、extern
作用、重定位、符号解析等
底层问题,写出更规范、更稳定的多文件项目

一.翻译环境

翻译环境就是把源代码转换成可执行程序(二进制)

其中有四步核心流程👉 :.c --> 预处理 --> .i --> 编译 --> .s --> 汇编 --> .o或.obj --> 链接 --> .exe

更具体的流程图如图所示:

1.1预处理

功能 :
把.i文件 --> 汇编代码.s

主要工作内容:

  1. 展开#include头文件,把内容插入进来
  2. 展开#define宏定义,并删除#define
  3. 删除所有注释
  4. 处理条件编译#if #ifdef #endif
  5. 添加行号、文件名,保留#pragma

指令(在gcc):

c 复制代码
gcc -E test.c -o test.i

🧐分析 :-E只进行预处理,停止在预处理阶段;-o是输出到指定文件

1.2编译

功能:

把.i文件 --> 汇编代码.s

步骤:

  1. 词法分析:拆分关键字、标识符、数字、符号
  2. 语法分析:生成语法树
  3. 语义分析:类型检查、匹配
  4. 优化:生成最优汇编代码

指令(在gcc):

c 复制代码
gcc -S test.i -o test.s

🧐分析 :-S只进行编译,生成汇编文件.s

1.3汇编

功能:

把汇编代码.s --> 机器指令(二进制目标文件.o或.obj)

特点:

  1. 不做优化
  2. 一条汇编指约等于一条机器指令

指令(在gcc):

c 复制代码
gcc -c test.s -o test.o

🧐分析 :-c只进行汇编,生成目标文件.o

1.4链接

功能:

把多个.o或.obj+库文件 --> 可执行文件.exe

主要工作内容:

  1. 符号解析:找到函数、全局变量的地址
  2. 重定位:修正所有调用地址
  3. 地址与空间分配

举个例子:

在add.c文件

c 复制代码
int g_val = 2022;
int Add(int x, int y)
{
    return x + y;
}

在test.c文件

c 复制代码
#include <stdio.h>

extern int Add(int x, int y);
extern int g_val;

int main()
{
    int sum = Add(10, 20);
    printf("%d\n", sum);
    printf("%d\n", g_val);
    
    return 0;
}

🧐分析 :
test.c单独编译生成test.o;add.c单独编译生成add.o

链接时:找到Add函数地址;找到g_val地址;修正调用指令 --> 重定位完成

二.运行环境

运行环境是执行已经生成好的可执行程序

运行步骤:

先把可执行程序加载到内存

⬇️

然后从main函数开始执行

⬇️

接着使用栈存放局部变量、函数调用

⬇️

再使用静态区存放全局变量、static变量

⬇️

最后程序结束

🎯总结

  1. 翻译环境 :源代码 --> 可执行程序,四步流程:预处理(test.c) --> 编译(test.i) --> 汇编(test.s) --> 链接(test.o或.obj),最后到可执行程序(test.exe)
  2. 预处理:展开头文件、宏、删注释
  3. 编译:生成汇编代码
  4. 汇编:生成机器码目标文件
  5. 链接:多文件合并、符号解析、重定位
  6. 运行环境 :加载内存、执行main、使用栈与静态区

⚠️易错点

  1. 以为.c直接变.exe,不知道四步流程
  2. 混淆编译和链接的职责
  3. 不知道预处理会删除注释、展开头文件和宏
  4. 多文件中忘记extern声明,链接报错
  5. 目标文件.o或.obj已是二进制,但不能直接运行
  6. 重定位是链接阶段完成,不是编译阶段

👀 关注 我们一路同行,从入门到大师,慢慢沉淀、稳步成长
❤️ 点赞 鼓励原创,让优质内容被更多人看见
⭐ 收藏 收好核心知识点与实战技巧,需要时随时查阅
💬 评论 分享你的疑问或踩坑经历,一起交流避坑、共同进步

相关推荐
鱼很腾apoc6 小时前
【MySQL】第4期 用户管理与 C 语言连接编程详解
linux·服务器·c语言·mysql·connector/c
himobrinehacken8 小时前
位运算揭秘:左右移与符号位陷阱
c语言·c++·算法·安全
水饺编程10 小时前
第2章:Linux 基础,rm 命令
linux·c语言·汇编
夏虫不可与之言冰11 小时前
第三课 点亮 LED 与定时器非阻塞闪烁
c语言·c++·vscode·单片机·嵌入式硬件·物联网
JasmineX-111 小时前
数据结构(笔记)——顺序栈
c语言·数据结构·笔记
2401_8628808211 小时前
嵌入式Linux系统移植与驱动开发完整指南
linux·c语言·驱动开发
我叫洋洋13 小时前
Cadence 16.6 从 OrCAD Capture 原理图到 Allegro PCB 全流程(含 5 个常见坑)
c语言·eda·嘉立创
水饺编程14 小时前
第2章:Linux 基础,关机命令
linux·c语言·汇编
Brilliantwxx15 小时前
【Linux】IO(上)全篇:文件本质、C 接口、系统调用与文件描述符
linux·运维·服务器·c语言
坐看风云变幻15 小时前
《嵌入式工程师的软硬件修仙之路》第 2 期|C 语言筑基:指针与内存模型
c语言·开发语言