【Linux】编译器-gcc/g++的使用(预处理、编译、汇编、连接)

目录

01.预处理(宏替换)

02.编译(生成汇编)

03.汇编(生成机器可识别码)

04.连接(生成可执行文件或库文件)

05.选项


编译器在编译代码时包含以下四个步骤:1.预处理 2.编译 3.汇编 4.连接 下面来一一介绍

格式:gcc [选项] 要编译的文件 [选项] [目标文件]

01.预处理(宏替换)

编译器预处理阶段主要负责处理源代码中的预处理指令,其中包括宏替换。

预处理器

编译器预处理阶段由预处理器负责执行。预处理器负责源代码中以‘#’开头的预处理指令,例如‘#define’、‘#include’、‘#ifdef’等,并将它们转换为相应的代码。

宏替换

宏替换是与处理区的一项重要功能。在预处理阶段,编译器会执行宏替换,将源代码中的宏定义替换为其相应的内容。宏定义通常使用‘#define’指令定义,例如

#define PI 3.14159

在预处理阶段,编译器会将代码中所有出现的‘PI’替换成‘3.14159’。

宏参数

宏定义可以嗲有参数,这样可以创建参数化的宏。例如:

#define MAX(x, y) ((x) > (y) ? (x) : (y))

宏展开

预处理器在进行宏替换时会执行宏展开,即将宏调用替换成宏定义的内容,在进行宏展开时,会递归地展开嵌套的宏调用,直到没有更多的宏调用为止。

实例

选项-E:该选项的作用是让gcc在预处理结束后停止编译过程。

选项-o:是指目标文件,“text.i”文件为已经过预处理的C原始程序。

02.编译(生成汇编)

在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。

词法分析

也称扫描器,它负责将源代码分解成单词,去除空白字符和注释。通常使用有限状态自动机或正则表达式来实现。

语法分析

也称解析器,它负责将词法分析器生成的单词流转换成抽象语法树。这个阶段检查语法错误,确保代码符合语言规范。

语义分析

语义分析器检查源代码中的语义错误,如类型不匹配、未声明的变量等。它还负责构建符号表以及执行类型推断等任务。

优化

在生成目标代码之前,编译器通常会对中间表示进行有害,以提高程序的性能和效率。优化技术包括常量折叠、循环展开、死代码删除等。

代码生成

在这个阶段,编译器将优化后的中间表示转换成目标机器的汇编代码或机器码。这个过程通常包括指令选择、寄存器分配、指令调度等步骤。

实例

选项-S:进行编译,生成汇编代码,并停止汇编过程。

03.汇编(生成机器可识别码)

汇编阶段是把编译阶段生成的“.s”文件转成目标文件

语法分析

在语法分析阶段,编译器会将源代码转换为中间表示形式,通常是抽象语法树或者中间代码。这个过程包括词法分析和语法分析。

词法分析器负责将源代码分解为单词或者标记,去除空格、注释等不必要的字符。

代码生成

代码生成阶段将中间表示形式转换为目标机器能够识别的汇编代码或者机器码。这个阶段包括指令选择、寄存器分配、指令调度等过程。

指令选择负责将中间表示的操作转换为目标机器的指令序列。寄存器分配则是将变量分配到寄存器或者内存位置,以最小化访存操作。指令调度会对指令序列进行重新排列,以优化执行顺序,提高指令级并行度和流水线利用率。

实例

选项-c:将汇编代码转化为二进制目标代码

04.连接(生成可执行文件或库文件)

在成功编译之后,就进入了链接阶段。

实例

输入./对程序进行执行

这里涉及一个重要的概念:函数库

我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有函数的定义,那么“printf”函数是哪里实现的呢?

事实上:系统把这些函数实现都被做到名为lib.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径“/user/lib”下进行查找,也就是链接到lib.so.6库函数中区,这样就能实现函数“printf”了,而这也就是链接的作用

函数库分为静态库及动态库:

  1. 静态库

    • 静态库是一组预编译的目标文件的集合,这些目标文件中包含了函数的实现和数据。
    • 静态库的文件扩展名通常为 .a(在Unix/Linux系统中)或 .lib(在Windows系统中)。
    • 当你使用静态库时,编译器会将库文件的代码复制到可执行文件中,使得可执行文件变得更大。这意味着可执行文件中包含了静态库中的所有函数和数据,使得可执行文件变得更加独立。
  2. 动态库

    • 动态库是一组预编译的目标文件的集合,与静态库不同的是,它们在程序运行时被动态加载到内存中。
    • 动态库的文件扩展名通常为 .so(在Unix/Linux系统中)或 .dll(在Windows系统中)。
    • 使用动态库可以减小可执行文件的大小,并且可以在运行时动态地加载和卸载库文件。这使得动态库在系统资源使用和代码更新方面更加灵活。

05.选项

除了以上的四个,gcc还有很多选项:

-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面

-S  编译到汇编语言不进行汇编和链接

-c  编译到目标代码

-o 文件输出到 文件

-static 此选项对生成的文件采用静态链接

-g 生成调试信息。GNU 调试器可利用该信息。

-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.

-O0

-O1

-O2

-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高

-w  不生成任何警告信息。

-Wall 生成所有警告信息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(三)复杂度的深层次剖析

之前发布了数据结构(一),很多同学反响不够清晰,那今天就发一篇对复杂度专题的博客,希望对大家理解复杂度提供一些帮助。 时间复杂度 我们先来一个理解一个复杂度,二分查找的复杂度(之前写过二…

app调用系统接口示意图

1.linux下app不能直接访问内核。 用户态和内核态 2. 系统调用是应用程序和系统内核之间的接口。 (1)app访问内核通过调用glibc中的系统调用接口(open()、read()、write()…

html5cssjs代码 024 响应式布局示例

html5&css&js代码 024 响应式布局示例 一、代码二、解释 该HTML代码重点在于构建一个带有响应式设计的两栏布局网页,包含页头、导航条、主要内容区(左右两列)和底部区域,并运用CSS样式设置页面元素的布局、颜色、字体、间…

C++特性三:多态---案例三(电脑组装)

案例描述: 电脑主要组成部件为 CPU(用于计算),显卡(用于显示),内存条(用于存储) 将每个零件封装出抽象基类,并且提供不同的厂商生产不同的零件,例…

PwnLab靶场PHP伪协议OSCP推荐代码审计命令劫持命令注入

下载链接:PwnLab: init ~ VulnHub 安装: 打开vxbox直接选择导入虚拟电脑即可 正文: 先用nmap扫描靶机ip nmap -sn 192.168.1.1/24 获取到靶机ip后,对靶机的端口进行扫描,并把结果输出到PwnLab文件夹下,命名…

杰发科技AC7801——Keil编译的Hex大小如何计算

编译结果是Keil里面前三个数据的总和: 即CodeRoDataRWData的总和。 通过ATCLinkTool工具查看内存,发现最后一个字节正好是5328 注意读内存数据时候需要强转成32位,加1000的 增加1024的地址只需要加256即可

【技术栈】Redis 删除策略

SueWakeup 个人主页:SueWakeup 系列专栏:学习技术栈 个性签名:保留赤子之心也许是种幸运吧 本文封面由 凯楠📸 友情提供 目录 相关传送门 前言 1. 删除策略的目标 2. 数据删除策略 2.1 定时删除 2.2 惰性删除 2.3 定期删除…

【S5PV210】 | GPIO编程

【S5PV210】 | GPIO编程 时间:2024年3月17日22:02:32 目录 文章目录 【`S5PV210`】 | `GPIO`编程目录1.参考2.`DataSheet`2.1.概述2.1.1.特色2.1.2 输入/输出配置2.1.3 `S5PV210` 输入/输出类型2.1.4 IO驱动强度**2.1.4.1 类型A IO驱动强度****2.1.4.2 类型A IO驱动强度****2…

Windows电源管理调节-Powercfg命令应用

Windows电源管理调节 PowerCfg命令介绍 在Windows下我们使用 powercfg.exe命令 来控制电源计划(也称为电源方案),以使用可用的睡眠状态、控制单个设备的电源状态,以及分析系统中常见的能效和电池寿命问题。 语法 Powercfg 命令行使用以下语法: powercfg /option [arg…

使用WordPress在US Domain Center上建立多语言网站的详细教程

第一部分:介绍多语言网站 多语言网站是一种可以用多种语言呈现内容的网站。它能够满足不同国家或地区用户的语言需求,提升网站的用户体验和可访问性。在WordPress中,您可以轻松地创建一个多语言网站,并通过插件来管理多语言内容&…

Go 1.22 - 更加强大的 Go 执行跟踪

原文:Michael Knyszek - 2024.03.14 runtime/trace 包含了一款强大的工具,用于理解和排查 Go 程序。这个功能可以生成一段时间内每个 goroutine 的执行追踪。然后,你可以使用 go tool trace 命令(或者优秀的开源工具 gotraceui&a…

漏洞发现-漏扫项目篇Poc开发Yaml语法插件一键生成匹配结果交互提取

知识点 1、Nuclei-Poc开发-环境配置&编写流程 2、Nuclei-Poc开发-Yaml语法&匹配提取 3、Nuclei-Poc开发-BurpSuite一键生成插件 章节点: 漏洞发现-Web&框架组件&中间件&APP&小程序&系统 扫描项目-综合漏扫&特征漏扫&被动漏扫…

C语言经典算法-8

文章目录 其他经典例题跳转链接41.基数排序法42.循序搜寻法(使用卫兵)43.二分搜寻法(搜寻原则的代表)44.插补搜寻法45.费氏搜寻法 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠…

Flutter开发进阶之使用Socket实现主机服务(二)

Flutter开发进阶之使用Socket实现主机服务(二) Flutter开发进阶之使用Socket实现主机服务(一) 在完成局域网内设备定位后就可以进入微服务的实操了。 I、构建Socket连接池 一、定义Socket 使用socket_io_client socket_io_client: ^2.0.3+1导入头文件 import packag…

LiveGBS流媒体平台GB/T28181功能-HTTPS 服务支持配置开启什么时候需要开启HTTPS测试SSL证书配置HTTPS测试证书

LiveGBS功能支持HTTPS 服务支持配置开启什么时候需要开启HTTPS测试SSL证书配置HTTPS测试证书 1、配置开启HTTPS1.1、准备https证书1.1.1、选择Nginx类型证书下载 1.2、配置 LiveCMS 开启 HTTPS1.2.1 web页面配置1.2.2 配置文件配置 2、HTTPS测试证书3、验证HTTPS服务4、为什么要…

图书馆管理系统 2.后台系统管理模块编写

后端 1.实体类编写 用户实体类 package jkw.pojo;import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data;import java.io.Serializable; import java.util.List;/*** 用户*/ Data public class …

机器学习 - 选择模型

接着这一篇博客做进一步说明: 机器学习 - 准备数据 PyTorch moduleExplaintorch.nnContains all of the building blocks for computational graphs (essentially a series of computations executed in a particular way). nn 模块为用户提供了丰富的神经网络组件…

【理解机器学习算法】之分类问题的模型评估(ROC-AUC)

ROC曲线(接收者操作特性曲线)和AUC(曲线下面积)是在不同阈值设置下,用于分类问题的性能度量工具。下面是它们所代表的含义以及使用方法: ROC曲线 代表含义:ROC曲线是一个图形化的表示&#xf…

反射 Reflection

反射 反射的概念 反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到加载完类之后,在堆中就产生了一个Class类型…

SurfaceFlinger实战dump获取单个Layer图像方案学员改进成果

背景: hi,粉丝朋友们: 在马哥课程的实战实现dump单个图层的发布后,很多学员朋友就纷纷享马哥要了相关源码,相关的链接请参考这里: https://blog.csdn.net/learnframework/article/details/136323076 学员…