【Linux】第二十九站:再谈进程地址空间

文章目录

  • 一、一些疑问
  • 二、程序没有加载前的地址(程序)
  • 三、程序加载后的地址
  • 四、动态库的地址

一、一些疑问

什么是虚拟地址?什么是物理地址?CPU读到的指令里面用的地址,是什么地址??

我们之前在使用动态库的时候,有一个选项-fPIC,它是与地址无关码。

二、程序没有加载前的地址(程序)

程序编译好之后,内部有地址的概念吗?

答案是有的!如下所示,其实在程序的内部,这些变量名都已经变成了地址了

image-20240115221708474

在以前还没有虚拟地址的时候,我们的程序一开始还没有被执行的时候,它就已经会被分成各个段。

而现在这些编译时的编址已经是平坦模式[0,4GB]。即它在编址的时候已经严格按照地址空间的方式进行编译代码的。所以说在磁盘上看到的可执行程序的顺序排布和以后的进程地址空间中的规则是一样的。

所以编译器也已经考虑了操作系统了!!!

如下所示

image-20240115222937589

这里的地址已经就是虚拟地址了!,也就是说可执行程序还没加载上去时候,已经是虚拟地址了,不过为了进行区分,在可执行程序还没有进行加载的时候,我们会把他叫做逻辑地址。如果是50多年前,逻辑地址和虚拟地址还是不一样的,不过现在逻辑地址,虚拟地址,线性地址等这些已经是同一个概念了,只不过逻辑地址一般是磁盘当中的可执行程序的地址

我们可以先随便写一点代码

image-20240116122853667

然后编译运行以下

image-20240116123628808

然后我们使用这个指令,这个指令可以直接将我们这个程序给反汇编出来

objdump -S a.out

比如下面的这一部分,左边的这一行就是每个指令的地址,每个指令都有不同的长度,有的是一个,有的是三个等等

三、程序加载后的地址

如下所示,当我们把代码和数据加载到内存的时候,当然要占据物理内存

image-20240116163034842

从而天然的就有了物理地址,所以当可执行程序加载到内存的时候,就有了两套地址,一套是逻辑地址,一套是物理地址。

那么如何执行第一条指令呢?

其实在可执行程序中已经有一个entry入口地址了,那么这个entry是不是物理地址呢?其实不是,因为它是在加载之前就有了,它就是一个逻辑地址。

我们之气那也说过,一个进程是有自己的cwd工作目录和exe能找到自己的可执行程序的

image-20240116165055082

当内核数据结构形成以后,我们可以将代码先加载到内存,当然也可以先不加载,我们这里先认为没有加载。它会先读取可执行程序的一些东西,将可执行程序的入口地址entry放到EIP/PC寄存器中。因为这个正好就是一个虚拟地址,所以就可以直接去正文代码中开始执行了,然后开始读取页表

image-20240116165440230

然后此时我们现在的页表并没有建立映射,那么就会产生缺页中断,就会将程序加载进去,然后它也就天然具有了物理地址。最终虚拟物理地址的映射在页表中也都有了

image-20240116165729953

然后就可以按照正常顺序去执行了。当我们读取到下面的那条函数调用指令的时候。

image-20240116170140088

我们会发现,CPU内部读到的指令,内部可能有数据,可能也有地址,而这里的地址就是虚拟地址!,这里的虚拟地址还是需要经过页表转换成物理地址,然后继续执行。如果这虚拟地址不存在,那么直接缺页中断即可。

而此时,我们就发现了,我们的程序中,从读取到的第一个指令,到CPU的处理,再到二次继续访问它,用的全部都是虚拟地址

image-20240116170541198

而这里其实就是编译器和操作系统相互协调的最重要的表现之一

四、动态库的地址

如下图所示

像这样的地址就是绝对地址

image-20240116171933485

还有一种地址是相对地址,或者称作逻辑地址,比如下面的例子,有一个100米的跑道,有一颗树在40m处,那么当我们处于50m处的时候,我们可以说绝对地址是50,也可以说相对地址是10。

image-20240116172036913

但是当这个树就在0处的时候,那么绝对地址就是相对地址或者逻辑地址

image-20240116172156637

而在我们前面的可执行程序中,就是因为相对都是从0开始的,所以可以叫做逻辑地址,虚拟地址,相对地址这些

如下图所示,是我们前面已经提过的

image-20240116175637827

现在当我们这个程序有一个printf时候,就需要调用动态库中的函数,然后它也要被加载到内存当中

image-20240116182932088

现在我们的问题是:共享库大了,具体映射到哪里呢?

我们现在这个0x1122这个地址是一个线性地址,我们的程序要跳转到对应的位置,它在共享库中也必须在对应的位置,即0x1122,否则找不到。

image-20240116183551742

所以它就必须得在固定地址处

但是这时候问题来了,一个进程可能要有十几个库,那么怎么能都加载到固定位置呢?

所以动态库被加载到固定地址空间中的位置是不可能的。

所以库要可以在虚拟内存中,任意位置加载!!!

所以库让自己内部函数不要采用绝对编址,只表示每个函数在库中的偏移量即可!!!

image-20240116184235911

这样的话,当代码要访问库中的方法时候,那么只需要起始地址+这个偏移量即可,从而进行对应找到代码

所以我们在前面说fPIC选项的时候,它是一个与位置无关码,意思就是直接用偏移量对库函数编址

静态库为什么不谈加载?不谈与位置无关?

因为静态库是直接被拷贝到可执行程序中的。就相当于库中的方法就是我们的方法。就直接用绝对编址进行编址了

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

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

相关文章

记录汇川:H5U与Factory IO测试14

现实53工位的物料运输。 设置了自动连续存启动:就是一个一个运,按照顺序将空的货架填满。 设置了自动连续存停止:就是完成当前循环后退出。 设置了自动连续取启动:就是一个一个运,按照顺序将有货的货架清空。 设置…

如何在Docker中搭建MinIO容器并实现无公网ip远程访问本地服务

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器,可以在各种环境中运行,例如本地、Docker容器、Kubernetes集群等。它兼…

Android Studio安装超详细步骤(包括SDK安装不成功,模拟器无法创建等问题)

本文主要介绍CPU为AMD锐龙和英特尔两种类型在安装中出现的一些问题,两种解决的方案不同,所以首先查看属于哪种,然后找相对应的安装方法。 Android Studio的安装需要准备两个安装文件,一个是java JDK ,一个是Android Studio均可在官…

kubesphere DevOps部署SpringCloud项目

🍎devops部署SpringCloud项目 🍅环境说明🍅部署流程🧁创建DevOps工程🧁填写流水线信息🧁创建流水线 🍅部署应用所需脚本🧁jenkinsfile🧁Dockerfile🧁deploy.y…

如何才能把图片无损放大?这几个无损放大的方法分享给你们

在互联网的浩瀚海洋里,我们常常迷失在繁星般的图片之中,寻找那一款能映照出我们内心的头像。无论是渴望在社交媒体上熠熠生辉,还是在游戏世界中塑造独一无二的形象,一个与我们心灵相通的头像总能带给我们难以言喻的喜悦与满足。然…

【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组

作者推荐 【矩阵快速幂】封装类及测试用例及样例 本文涉及知识点 动态规划 C算法&#xff1a;滑动窗口总结 LeetCode629: K 个逆序对数组 逆序对的定义如下&#xff1a;对于数组 nums 的第 i 个和第 j 个元素&#xff0c;如果满足 0 < i < j < nums.length 且 nu…

0、C++预备知识

文章目录 C与C语言为什么要学习CC为什么难学c值得学习的新特征C参考书籍开发工具 可移植性和标准程序创建的技巧编译和链接 C与C语言 C是一种计算机高级程序设计语言&#xff0c;C既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的基于对象的程序…

蓝莓产量预测(R语言版)

数据描述 字段名 描述 字段名 描述 id 蓝莓唯一标识 MinOfUpperTRange 花期内最高温带日平均气温的最低记录, Clonesize 蓝莓克隆平均大小 AverageOfUpperTRange 花期内最高温带日平均气温, Honeybee 蜜蜂密度 MaxOfLowerTRange 花期内最低温带日平均气温的最…

linux高级篇基础理论十二( 自动化运维工具Ansible )

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xff1a;云计算技…

vue-quill-editor 图片放大缩小 及富文本解析 放大图片预览

接上回 巴阿这是上一篇博客的标题 《vue vue-quill-editor 富文本编辑器 &#xff08;图片问题&#xff09;拦截粘贴动作 将粘贴的图片上传服务器 一个页面渲染多个富文本编辑器&#xff08;使用场景循环遍历 个数不定&#xff09;》 上篇传送门 需求1.编辑框里图片可放大缩…

什么是DNS(域名系统)

域名系统&#xff08;DNS&#xff09;像是互联网的电话簿&#xff0c;将人们容易记住的网址转换成计算机能理解的IP地址。 没有DNS&#xff0c;我们就需要记住复杂的数字序列来访问网站 DNS的基本概念 定义&#xff1a;DNS是一个分布式数据库&#xff0c;它将域名&#xff08…

阿里云服务器ECS性能与优势,为什么国内第一云?

为什么选择阿里云&#xff1f;阿里云服务器有哪些优势&#xff1f;阿里云全球第三&#xff0c;国内第一云&#xff0c;阿里云服务器网aliyunfuwuqi.com分享云服务器ECS在丰富ECS实例架构、弹性灵活、稳定可靠、便捷易用、安全保障和成本优化多方面优势&#xff1a; 阿里云服务…

BSP-D2000平台调试CM9434串口芯片

1.硬件原理图 原理图显示两块9434的INT分别接到D2000的GPIO0_A3和GPIO0_A5. 2.配置 2.1 设备树 gpio <&pio 1 1 1 1 1 0>;| | | | | | | || | | | | | | ------表示有效电平| | | | | | | | | …

走迷宫之推箱子

前言&#xff1a; 在上一篇文章当中我介绍了一个走迷宫的写法&#xff0c;但是那个迷宫没什么可玩性和趣味性&#xff0c;所以我打算在迷宫的基础上加上一个推箱子&#xff0c;使之有更好的操作空间&#xff0c;从而增强了游戏的可玩性和趣味性。 1. 打印菜单 void menu() {…

探索 Python:发现有趣的库——第 1 章:数据可视化之旅

在一个充满活力的科技世界中&#xff0c;数据分析专家“算法仙”和编程爱好者“代码侠”相遇了&#xff0c;决定一起踏上数据可视化的探险之旅。他们将运用 Matplotlib 和 Seaborn 这两个强大的 Python 库&#xff0c;将枯燥的数据转化为生动的图形。 算法仙&#xff1a;你好&…

Kafka 的 Consumer Group 解读

作为一份笔记&#xff0c;本文再次梳理一下 Kafka 的 Consumer Group。我们知道&#xff0c;一个 Topic 往往会有多个 Partition&#xff0c;一条消息只会被写到一个 Kafka 的 Partition 中&#xff0c;那 Consumer 是怎么消费 Message 的呢&#xff1f; Consumer Group 又从中…

如何低成本打造高效跨国企业内网

随着企业数字化转型的加速&#xff0c;企业对网络连接、安全性和可靠性的需求也变得越来越高&#xff0c;最近小编收到了好几封私信&#xff0c;咨询跨境企业内部组网方案。 投稿的是某跨国公司的IT运维人员&#xff0c;总部在海外&#xff0c;国内分支机构每天都需要进行数据互…

[Android]实现一个权限申请类

[Android]实现一个权限申请类 导言 在引入了动态权限申请之后&#xff0c;Android的权限申请就变得尤为繁琐&#xff0c;若是按照原有的方法一板一眼地进行申请&#xff0c;样板代码未免太多。因此本篇文章就使用ActivityResult API&#xff0c;来实现一个简单的权限申请类来帮…

C练习——魔术师猜三位数

题目&#xff1a; 有一种室内互动游戏&#xff0c;魔术师要每位观众心里想一个三位数abc&#xff08;a、b、c分别是百位、十位和个位数字&#xff09;&#xff0c;然后魔术师让观众心中记下acb、bac、bca、cab、cba五个数以及这5个数的和值。只要观众说出这个和是多少&#xf…

进程的创建与回收学习笔记

目录 一、进程内容&#xff1a; 二、进程常用命令 三、创建子进程 四、子进程进阶 五、进程的退出 六、进程的回收 一、进程内容&#xff1a; 程序&#xff1a; 存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09; 静态的 进程&#xff1a; 执行一个程序所…