当前位置: 首页 > news >正文

gcc编译的过程及每个过程的作用

在 C/C++ 开发中,gcc(GNU Compiler Collection)的编译过程通常分为4 个阶段,从源代码到可执行文件的转换依次经过:预处理(Preprocessing)→ 编译(Compilation)→ 汇(Assembly)→ 链接(Linking)。
    每个阶段的具体作用和输出如下:


    1. 预处理(Preprocessing)


        作用:处理源代码中的预处理指令(以 # 开头的命令),生成纯 C 代码(.i 文件)。主要操作:
        展开 #include 指令(将头文件内容插入到当前文件)。
        处理 #define 指令(替换宏定义,删除 #define 语句)。
        处理条件编译(#if、#ifdef、#else、#endif 等,保留符合条件的代码)。
        删除注释(替换为空格)。
        保留 #line 指令(用于后续调试时定位源代码位置)。
        命令示例:
        gcc -E hello.c -o hello.i  # -E 表示只进行预处理,-o 指定输出文件
        输入 / 输出:
        输入:.c 源代码文件(如 hello.c)
        输出:预处理后的 C 代码文件(如 hello.i,仍是文本文件)


    2. 编译(Compilation)


        作用:将预处理后的代码(.i 文件)翻译成汇编语言代码(.s 文件)。主要操作:
        进行语法分析、语义分析、词法分析(检查代码语法错误)。
        进行代码优化(如常量折叠、循环优化等,生成更高效的汇编代码)。
        将 C 代码转换为对应平台的汇编指令(与 CPU 架构相关)。
        命令示例:
        bash
        gcc -S hello.i -o hello.s  # -S 表示只编译到汇编阶段
        输入 / 输出:
        输入:预处理后的 .i 文件(如 hello.i)
        输出:汇编语言文件(如 hello.s,仍是文本文件,包含汇编指令)


    3. 汇编(Assembly)


        作用:将汇编代码(.s 文件)转换为机器码(二进制目标文件 .o 或 .obj)。主要操作:
        将汇编指令一一对应为 CPU 可识别的二进制机器码。
        生成符号表(记录变量、函数的地址信息,供后续链接使用)。
        不进行跨文件的符号解析(仅处理当前文件内的符号)。
        命令示例:
        gcc -c hello.s -o hello.o  # -c 表示只汇编到目标文件
        输入 / 输出:
        输入:汇编代码 .s 文件(如 hello.s)
        输出:二进制目标文件 .o(如 hello.o,不可直接执行,包含机器码和符号表)


    4. 链接(Linking)


        作用:将多个目标文件(.o)和库文件(如系统库、静态库、动态库)合并,生成可执行文件。主要操作:
        符号解析:将不同文件中的符号(变量、函数)关联起来(例如,main.c 中调用的 printf 函数需要关联到标准库中的实现)。
        重定位:调整目标文件中符号的地址(将相对地址转换为最终的绝对地址)。
        合并段表:将多个目标文件的代码段、数据段等合并为统一的段。
        命令示例:
        bash
        gcc hello.o -o hello  # 无特殊选项,默认执行链接过程
        输入 / 输出:
        输入:一个或多个 .o 目标文件、库文件(如 libc.so)
        输出:可执行文件(如 hello,可直接运行)
    总结
    gcc 编译的完整流程:hello.c →(预处理)→ hello.i →(编译)→ hello.s →(汇编)→ hello.o →(链接)→ hello(可执行文件)
    通过分步执行各阶段,可更清晰地调试代码(例如,预处理后查看宏展开结果,汇编后分析生成的指令等)。日常开发中,直接执行 gcc hello.c -o hello 会自动完成所有阶段。

http://www.dtcms.com/a/511429.html

相关文章:

  • ROS2[Humble] -- URDF Tutorial- 02-multipleshapes
  • C#实现二维码和条形码生成与打印
  • C#WPF如何跳转页面
  • 【高并发服务器】八、Poller描述符监控类实现
  • 用vs2013网站开发四川最好的网络优化公司
  • 如何开发一个 IDEA 插件通过 Ollama 调用大模型为方法生成仙侠风格的注释
  • 【论文精读】Latent-Shift:基于时间偏移模块的高效文本生成视频技术
  • unity基础学习笔记<上>
  • C# WPF Dragablz使用记录 TabControl选项卡可拖拽为单独界面或停靠
  • 机器人场景落地步入技术验证阶段,微美全息加快创新势能探索AI多元路径变革
  • YOLOv4 核心内容笔记
  • 网站开发工程师待遇家庭网站建设
  • 医疗门户网站模板wordpress3.8
  • iOS的多线程下数据安全和内存泄漏以及工具使用监测内存泄漏
  • 『CMake』关于使用CMake构建项目时的现代/传统指令
  • 请被人做网站怎么做倒计时网站
  • App开发框架调研对比
  • Ubuntu下载以及安装详解以及应用安装
  • 亚马逊云代理:AWS的EC2, S3, RDS,Lambda具体简介
  • 2640. QYQ在艾泽拉斯
  • 基于 React + TypeScript + Fabric.js 构建一个封面生成器网站
  • 营销型电子商务网站品牌建设与推广思路
  • 更新网站 seo公司的管理方式与管理方法
  • BZV49-C22,115稳压二极管 NXP安世半导体 工业电源芯片 芯片解析
  • 职场发展—如何避雷垃圾公司
  • 【Linux篇】软链接vs硬链接:Linux文件系统中的两种引用机制
  • C++ list核心接口与实战技巧
  • 微服务框架
  • 网站模块结构图wordpress调用栏目名称
  • 算法学习记录03——二叉树学习笔记:从两道题看透后序位置的关键作用​