个人对于“链接”的理解

一、概念:

链接是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。在现代操作系统中,链接是由叫做链接器的程序自动执行的。

链接器在软件开发中扮演着重要的角色,使得分离编译成为可能。我们不用将一个大型的应用程序组织为一个巨大的源文件,而是可以把它分解为更小、更好管理的模块,可以独立地修改和编译这些模块。链接通常是由链接器默默处理的。

二、静态链接

以一组可重定位目标文件(.o)和命令行参数作为输入,生成一个完全链接的、可以加载和运行的可执行目标文件作为输出。

为了构造可执行文件,链接器必须完成两个主要任务:

1、符号解析:目标文件定义和引用符号,每个符号对应于一个函数、一个全局变量或一个静态变量(即C语言中任何以static属性声明的变量)。符号解析的目的是将每个符号引用正好和一个符号定义关联起来。

2、重定位:编译器和汇编器生成从地址0开始的代码和数据节。链接器通过把每个符号定义与一个内存位置关联起来,从而重定位这些节,然后修改所有对这些符号的引用,使得它们指向这个内存位置。

目标文件纯粹是字节块的集合。这些块中,有些包含程序代码,有些包含程序数据,而其它的则包含引导链接器和加载器的数据结构。链接器将这些块连接起来,确定被连接块的运行时位置,并且修改代码和数据块中的各种位置。

三、目标文件

1、可重定位目标文件:包含二进制代码和数据,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件。

2、可执行目标文件:包含二进制代码和数据,其形式可以被直接复制到内存并执行。

3、共享目标文件:一种特殊类型的可重定位目标文件,可以在加载或者运行时被动态地加载进内存并链接。

四、符号和符号表

每个可重定位目标模块m都有一个符号表,它包含m定义和引用的符号的信息。在链接器的上下文中,有三种不同的符号:

1、由模块m定义并能够被其他模块引用的全局符号。全局链接器符号对应于非静态的C函数和全局变量。

2、由其他模块定义并被模块m引用的全局符号。这些符号称为外部符号,对应于在其他模块中定义的非静态C函数和全局变量。

3、只被模块m定义和引用的局部符号。它们对应于带static属性的C函数和全局变量。这些符号在模块m中任何位置都可见,但是不能被其他模块引用。

定义为带有C static属性的本地过程变量是不在栈中管理的。相反,编译器在.data或.bss中为每个定义分配空间,并在符号表中创建一个有唯一名字的本地链接器符号。

比如,假设在同一模块中的两个函数各自定义了一个静态局部变量x:

int f()
{static int x=0;return x;
}int g()
{static int x=1;return x;
}

在这种情况中,编译器向汇编器输出两个不同名字的局部链接器符号。比如,它可以用x.1表示函数f中的定义,而用x.2表示函数g中的定义。

注:使用static属性的函数和全局变量不可以在外部模块中被访问。

五、符号解析

链接器解析符号引用的方法是将每个引用与它输入的可重定位目标文件的符号表中的一个确定的符号定义关联起来。编译器只允许每个模块中每个局部符号有一个定义。静态局部变量也会有本地链接器符号,编译器还要确保它们拥有唯一的名字。

汇编器构造符号表,链接器进行符号解析。

1、链接器如何解析多重定义的全局符号?

链接器的输入是一组可重定位目标模块。

函数和已初始化的全局变量是强符号,未初始化的全局变量是弱符号。

规则1:不允许有多个同名的强符号。

规则2:如果有一个强符号和多个弱符号同名,那么选择强符号。

规则3:如果有多个弱符号同名,那么从选择这些弱符号中任意选择一个。

六、静态库

1、概念:所有的编译系统都提供一种机制,将所有相关的目标模块打包成为一个单独的文件,称为静态库,它可以用作链接器的输入。当链接器构造一个输出的可执行文件时,它只复制静态库里被应用程序引用的目标模块。
2、不使用静态库,编译器开发人员会用什么方法来向用户提供这些函数?

(1)让编译器辨认出对标准函数的调用,并直接生成相应的代码。

(2)将所有的标准C函数都放在一个单独的可重定位目标模块中,可以把这个模块链接到他们的可执行文件中。

这种方法的优点是:它将编译器的实现与标准函数的实现分离开来,并且仍然对程序员保持适度的便利。

但缺点是:(1)系统中每个可执行文件现在都包含着一份标准函数集合的完全副本,这对磁盘空间是很大的浪费。

(2)对任何标准函数的任何使用或者改变,无论多小的改变,都要求库的开发人员重新编译整个源文件。

静态库概念被提出来,解决这些不同方法的缺点。相关的函数可以被编译为独立的目标模块,然后封装成一个单独的静态库文件。然后,应用程序可以通过在命令行上指定单独的文件名字来使用这些在库中定义的函数。

比如,使用C标准库和数学库中函数的程序可以用以下形式的命令行来编译和链接:

gcc main.c /usr/lib/libm.a /usr/lib/libc/a

在链接时,链接器将只复制被程序引用的目标模块,这就减少了可执行文件在磁盘和内存中的大小。另一方面,应用程序员只需要包含较少的库文件的名字。

静态库以一种称为存档的特殊文件格式存放在磁盘中。

七、重定位

当汇编器生成一个目标模块时,它并不知道数据和代码最终将放在内存中的什么位置。它也不知道这个模块引用的任何外部定义的函数或者全局变量的位置。所以,无论何时汇编器遇到对最终位置未知的目标引用,它就会生成一个重定位条目,告诉链接器在将目标文件合并成可执行文件时如何修改这个引用。

八、动态链接共享库

静态库和所有的软件一样,需要定期维护和更新。

另一个问题是几乎每个C程序都使用标准I/O函数,比如printf和scanf。在运行时,这些函数的代码会被复制到每个运行进程的文本段中。在一个运行上百个进程的典型系统上,这将是对稀缺的内存系统资源的极大浪费。

共享库是一个目标模块,在运行或加载时,可以加载到任意的内存地址,并和一个在内存中的程序链接起来。这个过程称为动态链接,是由一个叫做动态链接器的程序来执行的。共享库也称为共享目标,微软的操作系统大量的使用共享库,它们称为DLL(动态链接库)。

共享库是以两种不同的方式来“共享”的。首先,在任何给定的文件系统中,对于一个库只有一个.so文件。所有引用该库的可执行目标文件共享这个.so文件中的代码和数据,而不是像静态库的内容那样被复制和嵌入到引用它们的可执行的文件中。其次在内存中,一个共享库的.text节的一个副本可以被不同的正在运行的进程共享。

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

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

相关文章

【错题集-编程题】四个选项(DFS + 剪枝 + 哈希表)

牛客对应题目链接:四个选项 (nowcoder.com) 一、分析题目 用递归枚举出所有的情况,注意剪枝: 填写某个数时,要看看还有没有剩余次数。填写某个数时,要看看符不符合若干题的选项必须相同。 二、代码 // 值得学习的代码…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(六)-人工智能控制的自主无人机用例

引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…

SparkStreaming--scala

文章目录 第1关:QueueStream代码 第2关:File Streams代码 第1关:QueueStream 任务描述 本关任务:编写一个清洗QueueStream数据的SparkStreaming程序。 相关知识 为了完成本关任务,你需要掌握:1.如何使用S…

OrangePi AI Pro 实测:感受 AI 应用的独特魅力与强大性能

OrangePi AiPro介绍和初始化配置 小寒有话说一、OrangePi AiPro介绍1. 主板详情2. 开发配置3. 镜像烧录4. 设备连接5. WiFi连接6. NVMe SSD的安装和挂载7. 更新下载源并下载必要的软件8. 扩展内存 二、Jupyter Lab AI测评应用案例1. 获取Jupyter Lab 网址链接2. 图像提取文字3.…

帕金森病患者应该如何进行日常锻炼以提高生活质量?

帕金森病患者的日常锻炼建议 帕金森病患者进行日常锻炼对于改善症状、维持肌肉功能和延缓疾病进展至关重要。以下是一些具体的锻炼建议: 选择适合的运动类型:帕金森病患者应选择低冲击、有氧的活动,如散步、骑自行车、游泳和太极拳等。这些运…

【qt】考试系统项目

话不多说,先一睹芳颜 咱们的账号,题库和答案都是通过文件获取的. 话不多说,直接开干 目录 一.登录窗口1.界面设计2.邮箱验证3.登录验证 二.题库窗口1.考试计时2.布局管理器3.题库显示4.按钮布局5.计算分数 三.窗口交互四.完整代码五.结语 一.登录窗口 1.界面设计 这里添加背…

【笔记】先求修改没保存的文本文件-在虚拟机中输入 yum makecache报错

所有者: root 日期: Sat Jul 13 03:10:34 2024 文件名: /etc/yum.repos.d/CentOS-Base.repo 修改过: 是 用户名: root 主机名: linuxlocalhost 进程 ID: 78107 正在打开文件 "CentOS-Base.repo" 日期: Sat Jul 13 03:18:24 2024 比交换文件新! (1) Anothe…

从信息化、数字化、智能化到企业大模型应用

新时代背景下,数字经济发展速度之快、辐射范围之广、影响程度之深前所未有,5G、大数据、云计算、人工智能、区块链等技术加速创新,全域融入经济社会、民生服务全过程,成为资源要素重组、经济结构重塑、竞争格局重构的关键力量。千…

jar服务注册为windows的服务

依赖工具:nssm.exe 使用NSSM (Non-Sucking Service Manager) NSSM是一个免费的开源工具,用于将任何应用程序注册为Windows服务。以下是如何使用NSSM将Java应用注册为服务的步骤: 步骤 1: 安装 NSSM 首先,你需要从NSSM的官方网站…

Visual Studio 安装程序无法执行修复或更新

一.问题场景 出现问题的场景:当你的VS已经安装但是无法在工具中下载新组件或者卸载了当时一直无法安装。 二.问题原因 如果计算机上的 Visual Studio 实例已损坏,则可能会出现此问题。 三.解决方法 如果之前尝试修复或更新 Visual Studio 失败&…

【Python】 使用 gne 库提取新闻标题的简易指南

我白天是个 搞笑废物 表演不在乎 夜晚变成 忧伤怪物 撕扯着孤独 我曾经是个 感性动物 小心地感触 现在变成 无关人物 🎵 张碧晨/王赫野《何物》 数据科学和网络爬虫领域,提取网页内容是一项常见任务。然而,不同的网站结…

浅谈RLHF---人类反馈强化学习

浅谈RLHF(人类反馈强化学习) RLHF(Reinforcement Learning fromHuman Feedback)人类反馈强化学习 RLHF是[Reinforcement Learning from Human Feedback的缩写,即从人类反馈中进行强化学习。这是一种结合了机器学习中…

Gridea + SFTP +Docker + Nginx 配置博客-CSDN

服务器选择 阿里云 ESC 服务器 比较便宜 99 一年开启密码登录配置你的远程服务域名选择自己的域名,当然我可以解析二级域名给大家不要搞我的服务器Remote Path 远程服务配置 配置自己的一个文件夹我是使用的 /gridea/blog (绝对路径)阿里云安…

探索AI艺术:简单方法训练你的AI画家(思路)

如何训练一个简单的AI画家模型 1. 确定问题和目标 在开始之前,明确你想要的输出类型和风格。例如,你是否想要生成逼真的风景画,还是抽象艺术作品?这将决定你选择的模型和数据集。 2. 准备数据集 收集和准备用于训练的艺术作品…

51单片机6(P0P1P2P3结构框架图)

一、GPIO结构框架图与工作原理 1、接下来我们介绍一下这个GPIO结构框图和工作原理,我们使用51单片机的GPIO分为了P0,P1,P2,P3这四组端口,下面我们就分别来介绍这四组端口它的一个内部结构,只有了解了内部的…

【React】监听浏览器返回事件

文章目录 popstate事件:点击浏览器前进,后退会触发popstate事件即,在同一文档的两个历史记录条目之间导航会触发该事件 useEffect(() > {const handlePageBack () > {// 此处写你想要触发的事件console.log(浏览器返回按钮被点击了&a…

[PM]原型与交互设计

原型分类 1.草图原型 手绘图稿, 规划的早期,整理思路会使用 2.低保真原型 简单交互, 无需配色, 黑白灰为主, 产品规划和评审阶段使用 标准化的低保真原型是高保真原型的基础 3.高保真原型 复杂交互, 一般用于公开演示, 产品先产出低保真原型, 设计师根据原型产出设计稿 低保…

Vue3学习体验(一)

搭建工程 使用vue-cli脚手架创建vue3工程 vue create vue3-app-vue-cliVue-cli官网:https://cli.vuejs.org/zh/guide/installation.html 使用vite搭建vue3工程 npm init表示临时的下载vite应用来创建vue3工程,工程名称为vue3-app-vite npm init vit…

mount挂载

1)Vmvare挂载光驱设备 安装光驱设备后,可以看到设备文件。 ls /dev/sr0 ll /dev/cdrom虽然设备是以文件的形式出现的,但和一般的文件不一样。 2)mount挂载 目录是目录,设备是设备,mount挂载可以让目录成…

数据结构——查找(线性表的查找与树表的查找)

目录 1.查找 1.查找的基本概念 1.在哪里找? 2.什么查找? 3.查找成功与否? 4.查找的目的是什么? 5.查找表怎么分类? 6.如何评价查找算法? 7.查找的过程中我们要研究什么? 2.线性表…