『Linux - gcc / g++』c程序翻译过程
文章目录
- 前言
- 预处理 -E
- 编译 -S
- 汇编 -c
- 链接
- 动静态链接
前言
在计算机中的每一个程序是由代码变化而来的,但是事实上来说,用 c/C++ 写出的代码是不能被计算机识别的,其中必须经过一系列的过程才能使这个代码能成功的被计算机识别;
这几个过程分别为:
| 预处理 | 编译 | 汇编 | 链接 |
预处理 -E
在预处理阶段时一般会进行:
- 去注释 - 将源文件中的注释使用"空格"代替;
- 宏替换 - 若是源文件中存在以#define定义的宏,则将其替换;
- 头文件展开 - 将头文件进行展开;
- 条件编译 - 根据条件编译中的条件,留下正确条件;
该些操作一般为文本操作,且该些操作结束后也仍为c/C++;
| g++ -E test.cpp | 将test.cpp文件进行预处理,并将预处理后的结果显示在显示器上; |
| g++ -E test.cpp -o test.i | 将test.cpp文件进行预处理,同时指定生成一个 test.i临时文件; |
| -E 指令 | 从现在开始进行程序的翻译,如果预处理完成则停止; |

从上图可以看出预处理前后的区别
可以看出两个文件大小的差距,源文件中的代码量大概只有23行,而再进行预处理过后,代码量变成接近三万行;
编译 -S
编译这个过程则是将预处理后的 .i 文件进行翻译,将c/C++代码翻译成汇编代码 .s文件;
| g++ -S test.i 或是 g++ -S test.i -o test.s | 将test.i文件编译成汇编语言 , 两种方法都可以生成test.s文件 ; 第二种方法可以指定生成文件的文件名(这里后缀一般不影响); |
| g++ -S test.cpp -o test.s | 作用同上,唯一不同的为这里将从test.cpp文件开始进行翻译,途中将要重新进行一次预处理;; |
| -E 指令 | 从现在开始进行程序的翻译直到编译完成; |

汇编 -c
在这个阶段过后,.s文件将会被转为可重定向二进制目标文件( .o 文件);
虽然这里转化为了二进制文件,但是仍然不能被计算机直接进行识别;
| g++ -c test.s 或是 g++ -c test.i -o test.o | 将汇编语言文件 test.s 进行汇编生成可重定向二进制目标文件 test.o |
| od 命令 | 将指定内容文件以八进制、十进制、十六进制、浮点格式或ASCII编码字符方式显示。默认使用的是八进制; |
| -c 指令 | 从现在开始进行程序翻译,直到汇编结束。 |

这里所生成的可重定向二进制文件并不能被执行;
这里或多或少可能会存在权限问题,因为所生成的可重定向二进制文件的权限为666 & (~umask)为664;
即没有运行的权限,为了排除该情况,修改文件权限;

但即使修改了文件权限也依然不能运行;
需要打开该文件即可以使用od命令将文件打开;

链接
这也是程序翻译的最后一个步骤,即将多个.o 或者 .obj 文件合并成一个可执行程序 .exe ;
| g++ test.cpp -o test 或 g++ -o test test.cpp | 将 test.cpp源文件编译生成 test可执行程序; |
然而在链接这一过程中也有分情况,分别为动态链接与静态链接;
动静态链接
在这之前首先要介绍两个命令:
| ldd filename | file filename |
|---|---|
| 查看该文件所依赖的库文件 | 可以查看文件的可执行程序状态(位数、动态链接等) |
![]() | ![]() |
一般的连接方式分为两种:
| a.动态链接 | b.静态链接 |
|---|---|
| 需要动态库 | 需要静态库 |
在调用函数中总是会包含各种头文件,但只有头文件是并不能将程序编译通过的;
头文件中只包含了各个函数的声明,而函数的定义一般以库的形式展示;
步骤一般为,在调用函数过后,从头文件中找到函数的声明,再去对应的库中找到函数的定义从而进行调用;
| 头文件 : 用来提供函数的声明 | 库文件 : 用来提供函数的定义(实现) |
|---|---|
![]() | ![]() |
自己写的源文件包含头文件,链接库文件才能生成一个可执行程序;
| 系统\库 | 动态库 | 静态库 |
|---|---|---|
| Linux | .so | .a |
| Windows | .dll | .lib |
在安装vs2019或者vs2022这种编译器时,虽然叫做配置环境,但是本质上是在安装所用语言的头文件以及库文件;
C程序是脱离不开库文件的;
在Linux中,许多的命令也是利用c语言实现的,例如在Linux中使用的ls命令;

在汇编过后所生成的可重定向二进制目标文件;

#include<iostream>int main()
{std::cout << "it's a test fail" << std:: endl;return 0;
}
从该文件中可以看到,该文件包含了一个文件 ,且调用了流插入<<流提取>>;
而这里生成的可重定向二进制文件只是将自己写的源文件中的代码生成可重定向的二进制目标文件;
至于代码中所包含的头文件以及使用流插入流提取并没有进行操作;
该操作将会在最后一步的链接过程中;
链接过程将会把该重定向二进制文件与对应的库文件进行链接最终生成一个可执行程序;(头文件在预处理阶段被展开)
| 静态链接 | 动态链接 | |
|---|---|---|
| 原理 | 在生成可执行文件的时候(链接阶段),把所有需要的函数的二进制代码都包含到可执行文件中去。因此,链接器需要知道参与链接的目标文件需要哪些函数,同时也要知道每个目标文件都能提供什么函数,这样链接器才能知道是不是每个目标文件所需要的函数都能正确地链接。如果某个目标文件需要的函数在参与链接的目标文件中找不到的话,链接器就报错了。目标文件中有两个重要的接口来提供这些信息:一个是符号表,另外一个是重定位表。 | 在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时连接的目的。 |
| 缺点 | 静态库的缺点为,若是多个文件同时调用同一个函数,则可能出现在一个项目中出现大量重复代码; | 动态库链接的缺点即为过于依赖动态库; |
| 方法 | g++ test.cpp -o test -static (-static : 表明使用静态链接的方式形成可执行程序) | g++ test.cpp -o test (默认即为动态链接) |

-
一般的机器可能会因为没有静态库而导致静态链接失败;
在Linux中,动态链接必须使用 .so 动态库文件;
静态链接必须使用 .a 静态库文件; -
若是没有静态库文件则需要进行安装 :
| c静态库安装命令 | C++静态库安装命令 |
|---|---|
| (sudo yum install -y glibc-static) | (sudo yum install -y libstdc+±static) |
相关文章:
『Linux - gcc / g++』c程序翻译过程
文章目录 前言预处理 -E编译 -S汇编 -c链接动静态链接 前言 在计算机中的每一个程序是由代码变化而来的,但是事实上来说,用 c/C 写出的代码是不能被计算机识别的,其中必须经过一系列的过程才能使这个代码能成功的被计算机识别; …...
苹果遭遇安全危机,应用商店曝出不良APP,或影响iPhone的销售
据澎湃新闻报道指苹果的App Store被曝出不良APP位居下载榜前列,这对于向来强调APP严格审核的苹果来说是巨大的打击,更影响向来被认为信息安全遥遥领先的名声,对当下正热销的iPhone15或造成打击。 据了解被曝的软件以“学习XX字母”为命名&…...
docker 基本操作
一、docker 概述 Docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行应用的开源工具,是一种轻量级的“虚拟机”。 Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自…...
ARM:使用汇编完成三个灯流水亮灭
1.汇编源代码 .text .global _start _start: 设置GPIOF寄存器的时钟使能LDR R0,0X50000A28LDR R1,[R0]ORR R1,R1,#(0x1<<5)STR R1,[R0]设置GPIOE寄存器的时钟使能LDR R0,0X50000A28LDR R1,[R0] 从r0为起始地址的4字节数据取出放在R1ORR R1,R1,#(0x1<<4) 第4位设…...
嵌入式养成计划-33--数据库-sqlite3
七十一、 数据库 71.1 数据库基本概念 数据(Data) 能够输入计算机并能被计算机程序识别和处理的信息集合数据库 (Database)数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合 常用的数据库 大型数…...
什么是大数据运维?大数据运维的职责
大数据运维是指管理、监控和维护大规模数据存储和处理平台的过程。它包含了对数据存储、处理、传输等方面的管理和维护,同时负责确保数据的安全性、可靠性和高效性。 大数据运维的职责包括以下几个方面: 确保大数据平台的高可用性和稳定性,…...
解决方案:AI赋能工业生产3.0,从工业“制造”到“智造”
视频监控技术是一种既成熟又广泛应用于工业制造领域的先进技术。它可以通过安装各种摄像头和传感器来监测整个生产流程,包括原材料的采购、加工、装配和物流等环节,从而实现对生产过程的实时监控和管理,以及对异常事件的及时预警和响应。 在…...
Android KeyStore 秘钥导入
源码参考: https://android.googlesource.com/platform/cts//master/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java 辅助源码参考: https://android.googlesource.com/platform/frameworks/base//master/core/java/android…...
TDengine+OpenVINO+AIxBoard,助力时序数据分类
时间序列数据分析在工业,能源,医疗,交通,金融,零售等多个领域都有广泛应用。其中时间序列数据分类是分析时序数据的常见任务之一。本文将通过一个具体的案例,介绍 Intel 团队如何使用 TDengine 作为基础软件…...
设计模式——16. 迭代器模式
1. 说明 迭代器模式(Iterator Pattern)是一种行为型设计模式,它用于提供一种访问聚合对象(如列表、数组、集合等)元素的统一接口,而不需要了解底层数据结构的具体实现。迭代器模式将遍历聚合对象的操作封装在一个独立的迭代器对象中,这样可以隔离遍历算法和数据结构,使…...
flink redis connector需要防止包冲突
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <dependency><groupId>org.apache.bahir</groupId><artifactId...
socket can查看详细信息 命令 ip -details -statistics link show can0
ip -details -statistics link show can0 ip -details link show can0 ip -statistics link show can0 也可以像第一行那样结合使用...
打造虚拟企业展厅,开启商务活动新时代
引言: 虚拟企业展厅是一种基于数字技术的全新商务模式,正在改变传统商务活动的方式,它比传统的企业展厅更便利,也更能凸显企业优势,展示企业风貌。 一.虚拟企业展厅的好处 1.打破地域限制 传统的商务活动通常需要参…...
03黑马店评-添加商户缓存和商户类型的缓存到Redis
商户查询缓存 什么是缓存 实际开发过程中数据量可以达到几千万,缓存可以作为避震器防止过高的数据访问猛冲系统,避免系统内的操作线程无法及时处理信息而瘫痪 缓存(Cache)就是数据交换的缓冲区(储存临时数据的地方),我们俗称的"缓存"实际就是缓冲区内的数据(一般从…...
LabVIEW玩转魔方
LabVIEW玩转魔方 使用LabVIEW创建一个3D魔方,并找出解谜题的秘密,给朋友留下深刻深刻的印象。游戏中内置的机制使每张脸都能独立转动,从而混合颜色。要解决难题,每个面必须是相同的纯色 魔方的奥秘在于它的简单性和不可解性。这是…...
大数据学习(1)-Hadoop
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博>主哦&#x…...
常用时序模型
常用时序模型 RNN (Recurrent Neural Network): 基本概念: RNN是一种可以处理序列数据的神经网络。它在每一时间步都接收一个新的输入,并将前一个时间步的隐藏状态作为额外的输入。问题: 它的主要问题是在处理长序列时遇到的梯度消失和梯度爆炸。这使得RNN难以捕获长期依赖关…...
阿里云/腾讯云国际站:私服服务器:什么是游戏虚拟服务器及用途讲解?
游戏虚拟服务器是一种新兴的技术,它可以为玩家提供更好的游戏体验。私服服务器它可以将游戏服务器的负载分散到多台服务器上,从而提高游戏的流畅度和稳定性。此外,游戏虚拟服务器还可以提供更多的游戏功能,比如游戏聊天室、游戏排…...
ssti 前置学习
python venv环境 可以把它想象成一个容器,该容器供你用来存放你的Python脚本以及安装各种Python第三方模块,容器里的环境和本机是完全分开的 创建venv环境安装flask #apt install python3.10-venv #cd /opt #python3 -m venv flask1 #cd /opt 选…...
uni-app:服务器端数据绘制echarts图标(renderjs解决手机端无法显示问题)
效果 代码 <template><view click"echarts.onClick" :prop"option" :change:prop"echarts.updateEcharts" id"echarts" class"echarts"></view> </template><script>export default {data()…...
Adafruit Bluefruit Playground:iOS与蓝牙开发板的物联网交互实战
1. 项目概述与核心价值 如果你手头有一块Adafruit的Circuit Playground Bluefruit或者CLUE开发板,想让它在你的iPhone或iPad上“活”起来,变成一个能远程控制彩灯、读取传感器数据甚至演奏音乐的智能玩具,那么Adafruit Bluefruit Playground …...
BepInEx 6.0.0插件框架技术架构深度解析:IL2CPP签名耗尽问题的根源与解决方案
BepInEx 6.0.0插件框架技术架构深度解析:IL2CPP签名耗尽问题的根源与解决方案 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx作为Unity游戏插件生态系统的核心…...
利用 STM32F407 BKPSRAM 实现运行时变量监控 —— 从方案到 Keil 调试实战
利用 STM32F407 BKPSRAM 实现运行时变量监控 —— 从方案到 Keil 调试实战 一、什么是 BKPSRAM 1.1 先看一张图 STM32F407 的存储系统里有一个很特别的区域叫备份域(Backup Domain)。备份域里住着几个东西: ┌───────────────…...
眉山奶油风家具的实际使用效果如何?奶油风家具
测评主体公示本次测评将对以下品牌进行对比:唯品名居家居、顾家家居、芝华仕、左右沙发、全友家居。所有品牌的测评将遵循统一标准,包括测评维度、动作、环境和数据采集方法。测评维度与标准1. 材质质量动作:检查家具表面材质、内部结构 过程…...
Docker 部署 SpringBoot 项目超详细教程
Docker 部署 SpringBoot 项目超详细教程一篇适合新手的 Docker 部署 SpringBoot 实战教程,包含: Docker 安装镜像加速SpringBoot 打包Dockerfile 编写构建镜像容器部署日志查看防火墙开放常见问题解决 图文并茂,保姆级教学。本文假设你已拥有…...
基于CircuitPython与伺服电机的自动调光眼镜制作指南
1. 项目概述与核心思路 最近在整理工作室的零件盒,翻出来一块Adafruit的Circuit Playground Express开发板和几个闲置的微伺服电机。看着窗外刺眼的阳光,我忽然想到,能不能用这些手头的“边角料”做个实用的小玩意儿?于是&#x…...
基于SpringBoot的门禁与访客管理系统毕业设计
博主介绍:✌ 专注于Java,python,✌关注✌私信我✌具体的问题,我会尽力帮助你。一、研究目的本研究旨在构建一个基于Spring Boot框架的门禁与访客管理系统以解决传统门禁系统在智能化管理方面存在的局限性。当前多数门禁系统仍采用封闭式架构设计导致数据…...
TLM通信:从基础操作到UVM高级连接模式
1. TLM通信基础:从信号级到事务级的跨越 第一次接触TLM这个概念时,我正被一堆信号线搞得焦头烂额。当时在做一个以太网MAC验证项目,每次调试都要跟踪几十根信号线的时序,简直像在解一团乱麻。直到同事提醒我:"为什…...
容器化应用分发平台seait:简化部署流程,实现一键运行
1. 项目概述:一个面向开发者的容器化应用分发平台最近在折腾个人项目部署和团队协作时,我一直在思考一个问题:如何能像分发一个可执行文件一样,轻松地分享和运行一个完整的、包含所有依赖的应用程序?尤其是在跨平台、跨…...
树莓派Pico舵机控制库picoclaw:从PWM原理到多舵机机器人应用
1. 项目概述:一个为树莓派Pico量身打造的舵机控制库如果你玩过树莓派Pico,并且尝试过用它来控制舵机,那你大概率会遇到一个头疼的问题:Pico的MicroPython固件本身并没有内置专门的舵机控制库。这意味着你需要自己动手,…...




