编译链接的过程发生了什么?
一:程序的翻译环境和执行环境
1:翻译环境:代码->二进制指令
2:执行环境:执行二进制指令
Q:我们写的代码是文本信息,而计算机执行的是二进制的指令,这二者之间如何进行的转换?
换句话说就是:翻译环境中发生了什么,才让代码->二进制指令?
解释: 我们写代码的文件叫作.c源文件,会经过编译器生成目标文件(不同环境和编译器的目标文件不同,比如VS是.obj,Linux环境下的gcc是.o),然后最后通过链接器把目标文件和链接库进行链接生成可执行程序。
这是一个在VS上写代码到生成可执行程序的过程,编译器为我们做了很多,才让我们能从源文件一下到目标文件,所以博主选择在Linux环境下的gcc编译器下进行细节上的演示,才能清楚的知道翻译环境到底发生了什么。
二:翻译环境工作图
解释:翻译环境分为四步
1:预编译(也叫作预处理)
2:编译
3:汇编
4:链接
三:翻译环境工作的展示
前提准备:
源文件创建及代码书写:
①:
我们创建一个在gcc中创建一个class110目录,在其下创建一个源文件test.c,在里面写上如图所示的代码
第一阶段:预编译
①: 然后在终端对test.c这个源文件进行gcc -E -o test.i(-E代表执行完预编译阶段就停止,然后放在test.i这个文件)
②:此时生成了test.i这个文件
③:将test.i和test.c进行对比
解释:
将test.i和test.c进行对比,我们能发现了第一阶段预编译的作用:
1:注释的删除
2:头文件的包含(test.i前面的800+行,就是#include<stdio.h>的内容)
3:#define符号的替换(直接把M替换成了100)
总结:所有的预处理指令(如文件包含、宏定义、条件编译等)都是在预编译阶段完成的。
这些统称为文本操作
第二阶段:编译
①:gcc -S test.i(对test.i进行 -S(执行完第二阶段编译就停止)放进自动生成的test.s中)
解释:此时打开test.s发现全是汇编代码, 所以第二阶段的工作是:将代码翻译成汇编代码,放进了自动生成的test.s中
第三阶段:汇编
①:gcc -c test.c(执行完第三阶段汇编就停止,放进自动生成的目标文件test.o中)
②:打开test.o,被警告
解释:打开test.o发现其是二进制文件,所以该阶段的功能:将汇编指令翻译成了二进制指令
③:强行打开目标文件test.o
解释:ELF是一种文件的格式 ,需要用指令readelf来读取ELF格式的文件
④:用指令readelf来读取ELF格式的文件
解释:此时返现我们需要输入一些选项(-a,-h,-l.......)来进行选择性的查看
⑤:-a选项,查看到段表
解释:这就是段表,也就是说ELF这种文件格式,其实是按照一个一个的段来存储的,这也是第四阶段链接中的功能合并段表中所谓的段表
⑥:-s来查看符号表
解释:
1:此时发现符号表中有我们代码的全局变量g_val,函数Add,函数main,库函数printf
2:这些都被存储到了符号表中 ,这就是第三阶段汇编的另一个作用,形成符号表,那么符号表是做什么的?在第四阶段里面有作用
第四阶段:链接
①:gcc test.o -0 test(链接生成可执行程序test)
②:打开可执行程序test
解释:可执行程序test依旧是一个二进制文件,也是可以用ELF打开的
四:链接的功能讲解:
①:假设两个.c源文件
解释:一个.c只是声明了Add函数,一个.add有函数的定义
②:链接的功能
解释:
1:每个源文件都在编译阶段 进行了符号汇总,然后在汇编阶段进行了形成符号表,即函数和对应的地址进行合并形成符号表(test.c的 Add是声明,所以地址是无效的)
2:在链接进行合并符号表,把两个源文件的符号表进行合并
3:Add的地址确认为有效地址(add.c中的函数地址)就叫作符号表的重定位
相关文章:

编译链接的过程发生了什么?
一:程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中,存在两个不同的环境。 第 1 种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第 2 种是执行环境,它用于实际执行代码 也就是说:↓ 1࿱…...

【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可…...

【Linux】 TCP短服务编写和守护进程
文章目录 TCP 短服务编写流程进程组和会话和守护进程 TCP 短服务编写流程 TCP服务器是面向连接的,客户端在发送数据之前需要先与服务器建立连接。 因此,TCP服务器需要能够监听客户端的连接请求。为了实现这一功能,需要将TCP服务器创建的套接字…...

自学数据库-MYSQL
自学数据库-MYSQL 一.表和视图1.表1.1 表创建1.2 索引1.2.1 这里是废话,不感兴趣的可以直接更具目录的跳过这里的内容1.2.1.1 索引是什么1.2.1.2 相关数据结构:二叉树、红黑树、B-Tree、BTree、Hash…①普通索引②唯一索引③全文索引④组合索引 1.3 表数据操作(更新…...

机器学习——多模态学习
多模态学习:机器学习领域的新视野 引言 多模态学习(Multimodal Learning)是机器学习中的一个前沿领域,它涉及处理和整合来自多个数据模式(如图像、文本、音频等)的信息。随着深度学习的蓬勃发展࿰…...

ceph掉电后无法启动osd,pgs unknown
处理办法: 只有1个osd,单副本,掉电损坏osd,只能考虑重建pg,丢失部分数据了。生产环境务必考虑2,3副本设计。避免掉电故障风险。 掉电后osdmap丢失无法启动osd的解决方案 - 武汉-磨渣 - 博客园 https://zhuanlan.zhih…...

HTML5实现古典音乐网站源码模板1
文章目录 1.设计来源1.1 网站首页1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面2.效果和源码2.1 动态效果2.2 源代码源码下载万套模板,程序开发,在线开发,在线沟通作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/142…...

快速生成单元测试
1. Squaretest插件 2. 依赖 <dependency><groupId>junit</groupId>...

WebGL系列教程十一(光照原理及Blinn Phong着色模型)
快速导航(持续更新中) WebGL系列教程一(开篇) WebGL系列教程二(环境搭建及着色器初始化) WebGL系列教程三(使用缓冲区绘制三角形) WebGL系列教程四(绘制彩色三角形&…...

《ASP.NET Web Forms 实现短视频点赞功能的完整示例》
在现代Web开发中,实现一个动态的点赞功能是非常常见的需求。本文将详细介绍如何在ASP.NET Web Forms中实现一个视频点赞功能,包括前端页面的展示和后端的处理逻辑。我们将确保点赞数量能够实时更新,而无需刷新整个页面。 技术栈 ASP.NET We…...

Linux SSH服务
Linux SSH(Secure Shell)服务是一种安全的远程登录协议,用于在Linux操作系统上远程登录和执行命令。它提供了加密的通信通道,可以在不安全的网络环境中安全地进行远程访问。 SSH服务在Linux系统中通常使用OpenSSH软件包来实现。它…...

MySQL--视图(详解)
目录 一、前言二、视图2.1概念2.2语法2.3创建视图2.3.1目的 2.4查看视图2.5修改数据2.5.1通过真实表修改数据,会影响视图2.5.2通过修改视图,会影响基表 2.6注意2.7 删除视图2.8 视图的优点 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&…...

Javascript 普通非async函数调用async函数
假设我们有一个异步函数 async function asyncFunction() {console.log("开始执行异步函数");await new Promise(resolve > setTimeout(resolve, 1000)); // 模拟异步操作console.log("异步函数执行完毕"); } 我们在调用这个异步函数时,比…...

【LeetCode】修炼之路-0004-Median of Two Sorted Arrays【python】
题目 Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). Example 1: Input: nums1 [1,3], nums2 [2] Output: 2.00000 Explanation: merged…...

C++面试速通宝典——10
177. #include <filename> 和 #include "filname.h" 有什么区别? 对于 #include <filename> , 编译器从标准库路径开始搜索 filename.h。 对于 #include "filename.h,编译器从用户的工作…...

肺腺癌预后新指标:全切片图像中三级淋巴结构密度的自动化量化|文献精析·24-10-09
小罗碎碎念 本期这篇文章,我去年分享过一次。当时发表在知乎上,没有标记参考文献,配图的清晰度也不够,并且分析的还不透彻,所以趁着国庆假期重新分析一下。 这篇文章的标题为《Computerized tertiary lymphoid structu…...

基于jmeter+perfmon的稳定性测试记录
1. 引子 最近承接了项目中一些性能测试的任务,因此决定记录一下,将测试的过程和一些心得收录下来。 说起来性能测试算是软件测试行业内,有些特殊的部分。这部分的测试活动,与传统的测试任务差别是比较大的,也比较依赖…...

前沿论文 M5Product 组会 PPT
对比学习(Contrast learning):对比学习是一种自监督学习方法,用于在没有标签的情况下,通过让模型学习哪些数据点相似或不同来学习数据集的一般特征。假设一个试图理解世界的新生婴儿。在家里,假设有两只猫和…...

navicat~导出数据库密码
当我们mysql密码忘记了,而在navicat里有记录,我们应该如何导出这个密码呢? 第一步:文件菜单,导出链接,导出连接获取到 connections.ncx 文件 这里需要勾选 导出密码!!! 不然导出的文…...

【Java】 —— 数据结构与集合源码:Vector、LinkedList在JDK8中的源码剖析
目录 7.2.4 Vector部分源码分析 7.3 链表LinkedList 7.3.1 链表与动态数组的区别 7.3.2 LinkedList源码分析 启示与开发建议 7.2.4 Vector部分源码分析 jdk1.8.0_271中: //属性 protected Object[] elementData; protected int elementCount;//构造器 public …...

YOLOv5改进——添加SimAM注意力机制
目录 一、SimAM注意力机制核心代码 二、修改common.py 三、修改yolo.py 三、建立yaml文件 四、验证 一、SimAM注意力机制核心代码 在models文件夹下新建modules文件夹,在modules文件夹下新建一个py文件。这里为simam.py。复制以下代码到文件里面。 import…...

SQL 自学:表别名的运用与对被联结表使用聚集函数
一、表别名的概念与作用 (一)表别名的定义 表别名是为表指定的临时名称,在 SQL 查询中使用别名可以简化表名,提高代码的可读性和可维护性。当表名较长或在复杂的查询中多次引用表时,使用表别名可以避免重复输入冗长的…...

jmeter学习(2)变量
1)用户定义的变量 路径:添加-》配置元件-》用户定义的变量 用户定义的变量是全局变量,可以跨线程组被调用,但在启动运行时获取一次值,在运行过程中不再动态获取值。 注意的是,如果在某个线程组定义了全…...

【C#生态园】C#文件压缩库全面比较:选择最适合你的库
从核心功能到API概览:深度解析六大C#文件压缩库 前言 在软件开发过程中,文件的压缩和解压缩是一个常见的需求。针对C#开发者而言,选择合适的文件压缩库可以极大地简化开发工作。本文将介绍几个常用的C#文件压缩库,包括其核心功能…...

【测试】接口测试与接口自动化
壹、接口测试基础 一、接口测试概念 I、基础概念 是测试系统组件间接口的一种测试。 主要用于检测外部系统与系统间、内部子系统间的交互点;测试重点检查数据的交换、传递和控制管理过程,以及系统间的相互逻辑依赖关系。 内部接口调用相当于函数调用&am…...

Android设置边框圆角
在Android开发中,圆角设计十分常见,那么实现边框圆角有几种形式呢? 文章目录 设置圆角边框样式使用ClipToOutline进行裁切最后 设置圆角边框样式 常见的方式是在drawable文件夹下设置一个xml文件的边框样式,比如 <shape andro…...

SpringBoot项目打成jar包,在其他项目中引用
1、首先新建一个SpringBoot工程 记得要将Gradle换成Maven 2、新建一个要引用的方法 3、打包的时候要注意: ① 不能使用springboot项目自带的打包插件进行打包,下面是自带的: ②要换成传统项目的maven打包,如下图: 依…...

【音频可视化】通过canvas绘制音频波形图
前言 这两天写项目刚好遇到Ai对话相关的需求,需要录音功能,绘制录制波形图,写了一个函数用canvas实现可视化,保留分享一下,有需要的直接粘贴即可,使用时传入一个1024长的,0-255大小的Uint8Arra…...

解决github每次pull push输入密码问题
# 解决git pull/push每次都需要输入密码问题 git bash进入你的项目目录,输入: git config --global credential.helper store然后你会在你本地生成一个文本,上边记录你的账号和密码。配置项写入到 "C:\Users\用户名\ .gitconfig" …...

Java重修笔记 第六十四天 坦克大战(十四)IO 流 - 标准输入输出流、InputStreamReader 和 OutputStreamWriter
标准输入输出流 1. System.in 标准输入流 本质上是一个InputString,对应键盘,表示从键盘输入。 定义:public final static InputStream in null; 所以 Scanner scanner new Scanner(System.in); 会从键盘中获取数据 2. System.out 标准输…...