news 2026/5/23 18:34:00

代码是如何变成可执行文件的?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
代码是如何变成可执行文件的?

代码是如何变成可执行文件的?—— 深入理解编译全过程

起因

前几天在公司,我的 mentor 突然问我:“代码在编译过程中,预处理阶段到底在做什么?”
我愣了一下,发现自己对这块知识的理解确实有些模糊。虽然每天都在写代码、编译、运行,但对背后的完整流程却一知半解。
于是,我决定重新梳理一遍,把这块基础补扎实,也便有了这篇博客。

全流程鸟瞰

用一句话概括:代码编译的过程,就是把“源代码”一步步变成“二进制可执行文件”的过程
这中间并不是一步到位,而是一条清晰的流水线:

源代码 ↓ 预处理 ↓ 编译 ↓ 汇编 ↓ 链接 ↓ 可执行文件

下面,我们就按照这个流程,逐一拆解每个阶段到底做了什么。


1. 预处理:纯文本处理阶段

预处理可以被看作是“编译前的准备”,它直接操作源代码文本,主要做以下几件事:

  • 展开#include:把头文件内容原样插入到对应位置。
  • 替换#define:将代码中的宏名替换成定义的文本或值。
  • 处理条件编译指令:根据#if#ifdef#ifndef等决定保留或删除某段代码。
  • 删除注释:将///* ... */注释全部移除。
  • 添加行号和文件名标识:便于后续调试和错误定位。

预处理完成后,我们得到的是一个“干净”的、没有注释、宏已展开、头文件已插入的源代码文本。


2. 编译:从源代码到中间表示

编译阶段是理解程序“语义”的过程,它把预处理后的源代码转化为中间代码或汇编代码。主要步骤包括:

  • 词法分析:把源代码拆成一个个 token(关键字、标识符、运算符等)。
  • 语法分析:根据语法规则构建抽象语法树(AST)。
  • 语义分析:检查类型是否匹配、变量是否声明等。
  • 生成中间代码:常是一种与机器无关的中间表示(如 LLVM IR)。
  • 代码优化:在-O2-O3等优化选项下,进行循环优化、内联、删除死代码等。

这个阶段结束后,我们得到的是汇编代码或某种中间代码,仍然是人可读(或半可读)的形式。


3. 汇编:转成机器指令

汇编阶段将上一步生成的汇编代码转换为机器可以执行的二进制指令:

  • 逐行翻译:把每一条汇编指令转换为对应的机器码。
  • 生成目标文件.o.obj):包含机器码、数据以及符号表(记录变量、函数名及其地址信息)。

目标文件已经是二进制格式,但还不能直接执行,因为可能还缺少一些外部函数或变量的定义。


4. 链接:拼成一个整体

链接是最后一步,负责把所有目标文件以及用到的库文件“组装”成一个可执行文件:

  • 合并多个.o文件:把不同模块的目标代码合并到一起。
  • 解析符号:找到所有函数、变量的实际地址。
  • 解决外部引用:处理extern声明的函数或变量。
  • 链接库文件:静态库(.a/.lib)会直接嵌入可执行文件;动态库(.so/.dll)则记录依赖关系,运行时加载。
  • 分配最终内存地址:为代码段、数据段等分配在内存中的运行地址。

最终,我们得到了一个可以在操作系统上直接执行的二进制文件。


为什么了解这些很重要?

了解编译全过程,不仅是为了回答 mentor 的问题,更是为了:

  • 更好地调试:知道错误发生在哪个阶段(预处理错误?链接错误?)。
  • 理解编译优化:明白-O2到底优化了什么。
  • 掌握大型项目构建:理解 Makefile、CMake 背后在做什么。
  • 深入系统理解:从代码到可执行文件,是理解计算机系统的重要一环。

结语

从一行行代码到一个可执行程序,背后是一条清晰而精致的流水线。
每个阶段各司其职,环环相扣,最终把我们的思想(代码)转化为机器可以理解和执行的形式。
重新走过一遍这条路,不仅解答了最初的疑问,也对编程这件事,多了一份系统级的理解。

希望这篇梳理,也能帮你理清这条“从源码到二进制”的路径。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 18:33:41

字节这款新AI让导演都慌了!Seedance2.0凭什么能自动剪大片?

📌 目录🎬 字节杀疯了!Seedance2.0自动剪大片,导演都慌了:这是要抢饭碗?一、核心黑科技:双分支大脑,终结AI音画错位的噩梦二、实测封神:多模态神操作,细节碾压…

作者头像 李华
网站建设 2026/5/21 23:37:10

折叠面板(Accordion)

折叠面板(Accordion) 引言 折叠面板(Accordion)是一种常见的界面元素,广泛应用于各种Web应用和桌面应用程序中。它通过将内容折叠成多个部分,使得用户可以快速地查看和隐藏信息,从而提高页面布局的整洁性和用户体验。本文将详细介绍折叠面板的设计原理、实现方式以及在…

作者头像 李华
网站建设 2026/5/10 1:29:24

Spring Boot 3 步完成日志脱敏,简单实用~

在我们写代码的时候,会书写许多日志代码,但是有些敏感数据是需要进行安全脱敏处理的。对于日志脱敏的方式有很多,常见的有:①使用conversionRule标签,继承MessageConverter ②书写一个脱敏工具类,在打印日志…

作者头像 李华
网站建设 2026/5/1 12:08:07

12.2 太牛了!批量传输技术竟然还能这样用?

太牛了!批量传输技术竟然还能这样用? 在WebSocket网关中,批量传输技术是提升系统吞吐量和降低网络开销的重要手段。通过将多个小消息合并为一个大消息进行传输,可以显著减少网络交互次数,提高传输效率。本章将深入探讨批量传输技术的实现原理和应用场景。 1. 批量传输概…

作者头像 李华
网站建设 2026/5/21 15:28:57

Spring AI Embedding 实战:从语义搜索到商品推荐系统

Spring AI Embedding 实战:从语义搜索到商品推荐系统 关键词:Spring AI / Embedding / 向量数据库 / PGVector / 推荐系统 / RAG 一、什么是 Spring AI Embedding Spring AI 中的 Embedding 技术核心在于将文本、图像等非结构化数据转化为高维向量(即 Embedding)。这些向量…

作者头像 李华
网站建设 2026/5/9 6:07:36

16.1 批量任务调度和心跳优化竟然还能这样做?

16.1 太震撼了!批量任务调度和心跳优化竟然还能这样做? 在分布式任务调度系统中,性能优化是确保系统能够处理大规模任务的关键。今天我们将深入探讨批量任务调度和心跳优化技术,这些技术能够显著提升系统的吞吐量和响应速度。 批量任务调度机制 批量任务调度是提升系统性…

作者头像 李华