编译链接的过程发生了什么?

news2024/11/18 16:55:21

一:程序的翻译环境和执行环境

ANSI C 的任何一种实现中,存在两个不同的环境。
1 种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
2 种是执行环境,它用于实际执行代码
也就是说:↓

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中的函数地址)就叫作符号表的重定位

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

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

相关文章

纠删码参数自适应匹配问题ECP-AMP实验方案(下)

7.参数选择 7.1.综合性能goal 根据权重和性能指标&#xff0c;本方案为每个文件确定最佳的纠删码参数&#xff0c;并将文件分组到不同的数据池中。本文使用了以下公式计算每个文件的评分&#xff0c;表示该文件在使用不同的纠删码参数时的综合性能。 s i j k ∑ j 1 6 c j…

2023 CCPC哈尔滨 报告

比赛链接&#xff1a;Dashboard - 10.6组队训练赛-2023CCPC哈尔滨站 - Codeforceshttps://codeforces.com/group/w6iGs8kreW/contest/552949 做题数&#xff1a;3 题 三题都是队友写的。所以来补一下 B L J。 B题&#xff1a; B. Memory Little G used to be a participant …

【MySQL】基本查询(上):创建、读取

1.Create(创建) 语法&#xff1a; INSERT [INTO] table_name [(column [, column] ...)] VALUES (value_list) [, (value_list)] ...value_list: value, [, value] ... 接下来我们用这个下表作为例子&#xff1a; -- 创建一张学生表 CREATE TABLE students ( id INT UNSIGN…

Http 协议和 RPC 协议有什么区别?

Http 协议和 RPC 协议有什么区别&#xff1f; 三个层面来述说&#xff1a; 从功能特性来说&#xff1a; HTTP是一个属于应用层的超文本传输协议&#xff0c;是万维网数据通信的基础&#xff0c;主要服务在网页端和服务端的数据传输上。 RPC是一个远程过程调用协议&#xff0…

【JS】哈希法解决两数之和

思路 使用哈希法&#xff1a;需要快速查询一个元素是否出现过&#xff0c;或者一个元素是否在集合里时 本题需要一个集合来存放我们遍历过的元素&#xff0c;然后在遍历数组的时候去询问这个集合&#xff0c;符合要求的某元素是否遍历过&#xff0c;也就是 是否出现在这个集合。…

【算法】链表:24.两两交换链表中的节点

目录 1、题目链接 2、题目介绍 3、解法 4、代码 1、题目链接 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 2、题目介绍 3、解法 引入伪头节点&#xff1a; 为了处理头节点可能被交换的情况&#xff0c;我们引入一个伪头节点&#xff08;dummy no…

jenkins远程调用

curl -G -d tokenfetch_coverage_token&systemmes2&typefull&envsit&resetno http://remote_user:1172e3d5524629fabef5dd55c652646232192.168.36.196:8080/job/fetch_coverage/buildWithParameters 在jenkins的用户界面设置一个token就可以了 remote_user 为…

Android笔记(二十四)基于Compose组件的MVVM模式和MVI模式的实现

仔细研究了一下MVI(Model-View-Intent)模式&#xff0c;发现它和MVVM模式非常的相识。在采用Android JetPack Compose组件下&#xff0c;MVI模式的实现和MVVM模式的实现非常的类似&#xff0c;都需要借助ViewModel实现业务逻辑和视图数据和状态的传递。在这篇文章中&#xff0c…

ESP32-C3实现UART

配置串口参数 在编写代码之前&#xff0c;你需要确定要使用的 UART 端口号和配置参数&#xff08;波特率、数据位、停止位等&#xff09;。 // 定义 UART 端口 #define TX_PIN 1 // TX 管脚 #define RX_PIN 3 // RX 管脚// 定义串口配置参数 #define UART_BAUDRATE 115200 // …

springboot 项目使用 gitlab 的 API

springboot 项目使用 gitlab 的 API 前言获取用户 access tokenSpring boot项目集成GitLab依赖1 pom依赖2 配置文件3 启动类4 核心代码gitlab 的 API 说明前言 需求是通过gitlab的api获取其中的数据。 gitlab官方API文档:https://docs.gitlab.com/ee/api/users.html gitla…

SpringBoot实现电子文件签字+合同系统

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 在现代企业中&#xff0c;合同管理和电子文件签字已成为日常运营不可或缺的一部分。为了提升效率和安全性&#xff0c;我们可以使用SpringBoot框架来实现一个电子文件签字和合同管理系统。本文将详细介绍如何…

腾讯云SDK连麦应用

音视频终端 SDK&#xff08;腾讯云视立方&#xff09;将新版连麦管理方案的多个功能集成至 腾讯云视立方控制台 > 连麦管理&#xff0c;便于用户快捷使用&#xff0c;具体分为快速上手、连麦应用、用量统计和地址生成器四个功能页面。更多连麦功能说明&#xff0c;请参见 新…

【算法刷题指南】BFS解决FloodFill算法

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

Leetcode - 周赛418

目录 一&#xff0c;3309. 连接二进制表示可形成的最大数值 二&#xff0c;3310. 移除可疑的方法 三&#xff0c;3311. 构造符合图结构的二维矩阵 四&#xff0c;3312. 查询排序后的最大公约数 一&#xff0c;3309. 连接二进制表示可形成的最大数值 本题数据范围较小&#…

sklearn机器学习实战——随机森林回归与特征重要性分析全过程(附完整代码和结果图)

sklearn机器学习实战——随机森林回归与特征重要性分析全过程&#xff08;附完整代码和结果图&#xff09; 关于作者 作者&#xff1a;小白熊 作者简介&#xff1a;精通python、matlab、c#语言&#xff0c;擅长机器学习&#xff0c;深度学习&#xff0c;机器视觉&#xff0c;目…

南京大学《软件分析》李越, 谭添——1. 导论

导论 主要概念: soundcompletePL领域概述 动手学习 本节无 文章目录 导论1. PL(Programming Language) 程序设计语言1.1 程序设计语言的三大研究方向1.2 与静态分析相关方向的介绍与对比静态程序分析动态软件测试形式化(formal)语义验证(verification) 2. 静态分析:2.1莱斯…

爆红网络的膨胀飞天视频,背后竟是Pika1.5 AI视频模型!

最近&#xff0c;社交网络上疯传着各种动物、建筑等物体膨胀飞上天的搞笑视频。无论是真实的还是虚构的物体&#xff0c;都在视频中被压扁、融化、膨胀&#xff0c;引发了广泛的病毒式传播。而这些有趣的效果&#xff0c;都是由Pika最新推出的1.5版本AI视频模型所制作的。 Ai …

STM32输入捕获模式详解(下篇):PWM输入捕获与PWI模式

1. 前言 在上篇文章中&#xff0c;我们详细介绍了STM32输入捕获模式的基本原理和应用方法&#xff0c;包括测频法和测周法。本文将重点探讨如何通过STM32的PWI&#xff08;PWM Input&#xff09;模式实现对PWM信号的频率和占空比测量。我们将结合具体的硬件电路&#xff0c;解…

[万字解析]从零开始使用transformers微调huggingface格式的中文Bert模型的过程以及可能出现的问题

系列文章目录 使用transformers中的pipeline调用huggingface中模型过程中可能遇到的问题和修改建议 [万字解析]从零开始使用transformers微调huggingface格式的中文Bert模型的过程以及可能出现的问题 文章目录 系列文章目录前言模型与数据集下载模型下载数据集下载 数据加载、…

单细胞转录组 —— simpleaf 原始数据处理

单细胞转录组 —— 原始数据处理实战&#xff08;simpleaf&#xff09; 前言 Alevin-fry 是一个快速、准确且内存节约的单细胞和单核数据处理工具。 Simpleaf 是用 Rust 编写的程序&#xff0c;它提供了一个统一且简化的界面&#xff0c;用于通过 alevin-fry 流程处理一些最…