GCC编译过程:预处理->编译->汇编->链接

目录

引言

 概括介绍

一、预处理

二、编译

三、汇编

四、链接

总结


引言

当使用集成开发环境(IDE)进行C语言编程时,点击"编译"按钮后,整个C程序从源代码到可执行文件的生成过程会自动完成。IDE会在后台为我们执行C语言的编译过程,将源代码转换为最终的可执行文件。虽然IDE隐藏了底层的细节,但理解编译过程对于程序员来说仍然是很有价值的。

 概括介绍

gccg++都是GNU编译器套件(GNU Compiler Collection,简称GCC)的一部分,其中gcc用于编译C语言代码,而g++用于编译C++语言代码。它们的编译过程在大部分情况下是类似的,但根据输入文件的扩展名和一些默认选项的不同,它们会调用不同的编译器前端,即C前端或C++前端。

下面是gccg++的编译过程的概述

  1. 预处理(Preprocessing):首先,对源文件进行预处理。预处理器将处理源代码中的预处理指令,比如以#开头的指令,如#include#define等,并展开宏定义。预处理后的代码会生成一个.i文件,通常是在临时目录中。

  2. 编译(Compiling):接下来,编译器前端会将预处理后的源代码编译成汇编代码(.s文件)。此阶段会检查语法和语义错误,并进行优化,但不会生成可执行代码。

  3. 汇编(Assembling):汇编器(as)将汇编代码转换成机器代码,并生成目标文件(.o文件)。

  4. 链接(Linking):最后,链接器(ld)将目标文件与所需的库文件链接在一起,生成最终的可执行文件。

下面让我们在Linux环境下简单示例C程序编译过程加深理解

代码示例(main.c):

#include<stdio.h>int main(){printf("Hello Linux\n");return 0;
}

一、预处理

预处理是编译过程的第一步,它处理以#开头的预处理指令,并展开宏定义。预处理器会执行以下主要任务:

  • 处理#include指令:将指定的头文件内容插入到源代码中。这样,可以在源文件中使用其他函数或变量的声明和定义。

  • 处理宏定义:将代码中定义的宏展开为对应的表达式或语句。例如,#define MAX_VALUE 100将会在源代码中把所有MAX_VALUE替换为100

  • 处理条件编译指令:如#ifdef#ifndef#if等,这些指令根据条件判断是否编译部分代码块。

预处理后的代码会生成一个.i文件,这是一个展开了所有宏和包含了所有头文件的中间文件。

语法示例

gcc -E main.c -o main.i

 命令中-E是让编译器在预处理之后就退出,不进行后续编译过程,-o是指定输出文件名。

使用该指令的结果是将stdio.h文件全部内容插入到main.c形成main.i文件。

可以看到预处理之后的main.i文件显然比main.c文件大得多。我们查看一下main.i文件,因为此时main.i依然是文本文件。

(使用head指令查看main.i文件)

二、编译

编译是预处理后代码的第二个阶段。编译器前端(例如cc1cc1plus)接收预处理后的代码,并将其转换成汇编代码。在编译阶段,编译器执行以下主要任务:

  • 语法和语义检查:编译器检查代码是否符合C/C++语法规则,并进行语义分析,以确保代码没有逻辑错误。

  • 生成中间表示:编译器将代码转换成中间表示形式,通常是一种低级的、与特定硬件无关的表示。

  • 优化:编译器可能对中间表示进行优化,以提高程序的执行效率和代码质量。

编译阶段不会生成可执行文件,而是将代码转换成汇编代码,通常保存为.s文件。

语法示例

gcc -S main.i -o main.s

命令中-S让编译器在编译之后停止,不进行后续编译过程,-o是指定输出文件名。

编译成汇编文件大小已经非常小了,相对于预处理之后的main.i文件小很多。

编译过程完成后,将生成程序的汇编代码test.s,这也是文本文件。我们查看一下。

 图中即为main.s中的汇编代码。

三、汇编

在汇编阶段,汇编器(as)接收编译生成的汇编代码,并将其转换为机器代码。汇编器的任务包括:

  • 将汇编代码转换为机器代码:将汇编代码中的汇编指令翻译成特定硬件架构能理解的机器指令。

  • 生成目标文件:生成一个或多个目标文件(.o文件),每个文件对应一个源文件或编译单元。

目标文件是机器代码的二进制表示形式,但它们还不是最终可执行的程序,因为某些符号引用可能仍然未解析。

语法示例

gcc -c main.s -o main.o

命令中-c选项,它告诉gcc只进行编译,不进行链接。因此,这个命令只会将汇编代码转换为目标文件,而不会生成可执行文件。-o是指定输出文件名。

目标文件test.o二进制表示的机器代码,可以作为链接的输入,用于生成最终的可执行文件。

四、链接

  • 链接器接收一个或多个目标文件,以及所需的库文件,并将它们合并成最终的可执行文件。
  • 链接器解析目标文件中的符号引用,找到对应的符号定义,并将符号重定位,以便正确地指向它们的定义。
  • 合并库文件,生成完整的可执行文件,其中包含所有的机器代码和解析后的符号。

语法示例

gcc main.o -o main

命令gcc main.o -o main是将目标文件(main.o)链接为可执行文件(main)的gcc命令。在这个命令中,我们没有使用-c选项,因此gcc会进行链接操作,生成最终的可执行文件。

当执行gcc main.o -o main命令时,gcc会将目标文件main.o与所需的库文件(如果有的话)一起进行链接,并生成最终的可执行文件main。这个可执行文件就是可以在Linux下运行的C程序。

 执行./main命令会运行名为main的可执行文件。这是我们之前用gcc命令生成的C程序的可执行文件。

总结

生成可执行程序过程为成四个步骤:

  1. 由.c文件到.i文件,这个过程叫预处理。
  2. 由.i文件到.s文件,这个过程叫编译。
  3. 由.s文件到.o文件,这个过程叫汇编。
  4. 由.o文件到可执行文件,这个过程叫链接。

在集成开发环境中,点击"编译"按钮后,IDE会自动完成上述四个阶段,无需手动执行每个步骤。如果没有编译错误,最终的可执行文件将生成并可以在IDE中直接运行。

虽然IDE为我们提供了方便的编译工具,但了解C语言的编译过程仍然对于程序员来说是重要的,特别是在解决一些编译错误或进行优化时,理解底层过程可以帮助我们更好地理解和改进代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT QLCDNumber 使用详解

本文详细的介绍了QLCDNumber控件的各种操作&#xff0c;例如&#xff1a;新建界面、源文件、设置显示位数、设置进制、设置外观、设置小数点、设置溢出、显示事件、其它文章等等操作。 实际开发中&#xff0c;一个界面上可能包含十几个控件&#xff0c;手动调整它们的位置既费时…

Activity启动过程详解(Android 12源码分析)

Activity的启动方式 启动一个Activity&#xff0c;通常有两种情况&#xff0c;一种是在应用内部启动Activity&#xff0c;另一种是Launcher启动 1、应用内启动 通过startActivity来启动Activity 启动流程&#xff1a; 一、Activity启动的发起 二、Activity的管理——ATMS 三、…

怎么在JMeter中的实现关联

我们一直用的phpwind这个系统做为演示系统, 如果没有配置好的同学, 请快速配置之后接着往下看哦. phpwind发贴时由于随着登陆用户的改变, verifycode是动态变化的, 因此需要用到关联. LoadRunner的关联函数是reg_save_param, Jmeter的关联则是利用后置处理器来完成. 在需要查…

字节编码学习

字节编码学习 文章目录 字节编码学习01_字节与ASCII码表02_每个国家都有独特的码表03_国际化UTF-804_编码本和解码本不一致&#xff0c;乱码 01_字节与ASCII码表 public class Demo01 {public static void main(String[] args) {// 计算机的底层全部都是字节 ---- ----// 一个…

1.利用matlab建立符号表达式(matlab程序)

1.简述 、 1. 使用sym命令创建符号变量和表达式 语法&#xff1a; sym(‘变量’,参数) %把变量定义为符号对象 说明&#xff1a;参数用来设置限定符号变量的数学特性&#xff0c;可以选择为’positive’、’real’和’unreal’&#xff0c; ’positive’ 表示为“正、实”符…

C++的auto究竟是何方神圣

C的auto究竟是何方神圣 前言&#x1f64c;auto&#xff08;C 11&#xff09; 的使用细则auto是什么&#xff1f; auto声明的变量是在什么时期被编译器推导出来呢&#xff1f;为什么使用auto进行定义变量时&#xff0c;必须进行初始化&#xff1f; auto 的使用场景auto与指针和引…

软件安全测试包含哪些内容和方法?安全测试报告的必要性

软件安全测试是一种通过模拟真实攻击的方式&#xff0c;对软件系统进行全面的安全性评估和测试&#xff0c;以发现潜在的安全漏洞和弱点&#xff0c;是确保软件系统安全性的重要措施。在进行软件安全测试时&#xff0c;我们需要了解测试的内容和方法&#xff0c;以及为什么进行…

FastAPI 构建 API 高性能的 web 框架(一)

如果要部署一些大模型一般langchainfastapi&#xff0c;或者fastchat&#xff0c; 先大概了解一下fastapi,本篇主要就是贴几个实际例子。 官方文档地址&#xff1a; https://fastapi.tiangolo.com/zh/ 1 案例1:复旦MOSS大模型fastapi接口服务 来源&#xff1a;大语言模型工程…

C语言学习笔记 vscode使用外部console-11

前言 在默认情况下&#xff0c;我们运行C语言程序都是在vscode终端的&#xff0c;在小程序运行时这个是没有问题的&#xff0c;但是当程序变得复杂它就不好用了&#xff0c;这时我们可以将这个终端设置为外部console&#xff0c;这样方便处理更多、更复杂的程序。 步骤 1.点击…

PCB电路板设计基础入门学习笔记

文章目录&#xff1a; 一&#xff1a;Arduino线路板绘制&#xff08;原理图库、PCB库、原理图、PCB图绘制&#xff09; 1.原理图库绘制Schematic Library&#xff08;有现成库&#xff0c;没有就自己画&#xff09;[SCH Library] 方法一&#xff1a;自己依次画 ATMEGA328P-…

HTTP——十一、Web的攻击技术

HTTP 一、针对Web的攻击技术1、HTTP 不具备必要的安全功能2、在客户端即可篡改请求3、针对Web应用的攻击模式 二、因输出值转义不完全引发的安全漏洞1、跨站脚本攻击2、SQL 注入攻击3、OS命令注入攻击4、HTTP首部注入攻击5、邮件首部注入攻击6、目录遍历攻击7、远程文件包含漏洞…

【cluster_block_exception】写操作elasticsearch索引报错

【cluster_block_exception】操作elasticsearch索引b报错 背景导致原因&#xff1a;解决方法&#xff1a; 背景 今天线上elk的数据太多&#xff0c;服务器的空间不足了。所以打算删除一些没用用的数据。我是用下面的request&#xff1a; POST /{index_name}/_delete_by_query…

Promise详细版

promise基础原理到难点分析 常见的Promise的方法解读 扩展async和await深入分析 逐步分析Promise底层逻辑代码 一、Promise基础 1.什么是promise 为了解决回调地狱&#xff1a; //2.设置点击事件btn.onclick function() {//3.创建ajax实例化对象let xhr new XMLHttpRe…

流量,日志分析

wireshark wireshark中有捕获过滤器和显示过滤器 常用的捕获过滤表达式&#xff1a; 常见的显示过滤表达式&#xff1a; 语法&#xff1a; 1.过滤IP&#xff0c;如来源IP或者目标IP等于某个IP 例子: ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107 或者 ip.addr eq 1…

DAY03_Spring—SpringAOPAOP切入点表达式AOP通知类型Spring事务管理

目录 一 AOP1 AOP简介问题导入1.1 AOP简介和作用1.2 AOP中的核心概念 2 AOP入门案例问题导入2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三步】定义通知类&#xff0c;制作通知方法【第四步】定义切入点表达式、配…

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image&#xff1a;嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio&#xff1a;嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video&#xff1a;嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…

MySQL面试1

Mysql的面试突击1 Mysql的体系结构是什么样子的&#xff08;查询语句怎么进行执行的&#xff09; mysql的架构&#xff1a;单进程多线程的架构模式 CLient -----> Server架构 Mysql的链接方式有没有性能优化的点 2个点 查询缓存(Query Cache) MySQL 内部自带了一个缓存模…

Spring Boot集成EasyExcel实现excel导入导出操作

文章目录 Spring Boot集成EasyExcel实现excel导入导出操作0 简要说明简单使用读操作excel源文件实体类监听器业务代码 写操作*实体类*excel示例业务代码根据参数指定列导出指定哪几列导出复杂头导出 关于数值型&#xff0c;日期型&#xff0c;浮点型数据解决方案实体类接收字符…

算法通过村第二关-链表黄金笔记|K个一组反转

文章目录 前言链表反转|K个一组翻转链表解题方法&#xff1a;头插法处理&#xff1a;穿针引线法处理&#xff1a; 总结 前言 提示&#xff1a;没有人天生就喜欢一种气味而讨厌另一种气味。文明的暗示而已。 链表反转|K个一组翻转链表 给你链表的头节点 head &#xff0c;每 k…

【css】textarea-通过resize:none 禁止拖动设置大小

使用 resize 属性可防止调整 textareas 的大小&#xff08;禁用右下角的“抓取器”&#xff09;&#xff1a; 没有设置resize:none 代码&#xff1a; <!DOCTYPE html> <html> <head> <style> textarea {width: 100%;height: 150px;padding: 12px 20p…