linux中的所有C程序的加载地址都是通用的吗?

2023-12-06

假设我有一个 prog1.c,它构建为 prog1.out。在 prog1.out 中有一个链接器信息,它将告诉 elf 将被加载到哪里。这些地址将是虚拟地址。加载程序将查找这些信息并将其作为一个进程启动。 DS、BSS 等每个部分都将加载到链接器中提到的虚拟地址上。例如,我有 prog2.out 也有相同的加载器地址、BSS、DS 等,那么它会冲突吗?我知道这不会冲突,但会出现性能问题。既然两个进程具有相同的虚拟地址但它们映射到不同的物理地址?我很困惑,它如何保护具有相同虚拟地址的两个进程。


问题是,当进程使用内存地址时,它正在谈论虚拟地址,该地址可能与同一物理地址不同。这意味着两个进程可以引用相同的地址并且不会混合它们的数据,因为它将位于两个不同的物理位置。

下面我描述了典型计算机上虚拟地址如何转换为物理地址(这在其他体系结构上略有不同,但都是相同的想法)

了解 Intel x86 架构上的内存转换过程(3 级分页)

因此,一方面你有一个虚拟内存地址,并且你想获取一个物理内存地址(即:RAM 上的实际地址),工作流程主要是这样的:

虚拟地址 -> [分段单元] -> [分页单元] -> 物理地址

每个操作系统都可以定义分段单元和分页的工作方式。例如,Linux 使用平面分割模型,这意味着它被忽略,所以我们现在会做同样的事情。

现在,我们的虚拟地址通过称为分页单元的东西,并以某种方式转换为物理地址。这就是方法。

内存被分成一定大小的块,在 intel 上此大小可能是 4KB 或 4MB。

每个进程在内存中定义一组表,以便计算机知道应该如何转换内存地址。这些表以分层方式组织,实际上,您要访问的内存地址被分解在这些表的索引中。

我知道,这听起来令人困惑,但请继续听我说几句话。你可以通过这张图片来关注我的写作:

x86 32 bit paging (from wikipedia)

CPU内部有一个寄存器,叫做CR3它存储第一个表的基地址(我们将这个表称为页目录,它的每个条目称为页目录条目)。当一个进程正在执行时,它的CR3已加载(除其他外)。

所以,现在你想要访问,比如说,内存地址0x00C30404,

分页单元说“好吧,让我们获取页目录基址”,查看CR3寄存器并知道页目录基址在哪里,我们称这个地址为PDB(页目录基址)。

现在您想知道应该使用哪个目录条目。正如我之前所说,地址被分解为一堆索引。最高有效 10 位(位 22 到 31)对应于页目录的索引。在这种情况下,0x00C30404 is 0000 0000 1100 0011 0000 0100 0000 0100以二进制表示,其最高 10 位为:0000 0000 11这是0x3。这意味着我们要寻找第三页目录条目。

我们现在干什么?

请记住,这些表是分层的:每个表页面目录条目除其他外,还有下一个表的地址,称为页表。 (此表可能因每个页面目录条目).

现在,我们得到了另一个表。地址的接下来 10 位将告诉我们将访问该表的哪个索引(我们将其称为页表条目)。

00 0011 0000是接下来的 10 位,它们是数字:0x30。这意味着我们必须访问第 30 个页表项..

最后,这个页表项保存所需的偏移量页框(请记住,内存被划分为 4k 的块)。最后,我们地址的最低有效 12 位是该地址的内存偏移量页框,请注意页框是实际的物理内存地址。

这称为 3 级分页,在 64 位(或使用 PAE)上非常相似,但多了一层分页。

您可能认为仅仅为了获取变量而获取所有这些内存访问真是太糟糕了。这是事实。计算机中有一些机制可以避免所有这些步骤,其中之一就是TLB(Table Lookaside Buffer),它存储所有已完成翻译的缓存,因此可以轻松获取内存。

此外,这些结构的每个条目都有一些有关权限的属性,例如“此页面可写吗?” “此页面可执行吗?”。

所以,现在您了解了内存分页的工作原理,就很容易掌握 Linux 如何处理内存了:

  • 每个进程都有自己的 CR3,当计划运行进程时,会加载 cr3 寄存器。
  • 每个进程都有自己的虚拟空间(表可能未满,进程可以从例如 4kb 的单页开始)。
  • 每个进程都映射了一些其他页面(操作系统内存),因此当它被中断时,中断处理程序会启动同一任务并处理该任务中的中断,从而执行所需的代码。

此类计划的一些动机

  • 您不必同时拥有所有进程的内存,您可以将一些内存存储在磁盘中。
  • 您可以安全地隔离每个进程内存,并为其授予一些权限。
  • 一个进程可以使用 10MB 的 RAM,但它们不需要在物理内存中是连续的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux中的所有C程序的加载地址都是通用的吗? 的相关文章

  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 在 MacO 和 Linux 上安装 win32com [重复]

    这个问题在这里已经有答案了 我的问题很简单 我可以安装吗win32com蟒蛇API pywin32特别是 在非 Windows 操作系统上 我一直在Mac上尝试多个版本pip install pywin32 都失败了 下面是一个例子 如果你
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 在 ASP.NET 中将事件冒泡为父级

    我已经说过 ASP NET 中的层次结构 page user control 1 user control 2 control 3 我想要做的是 当控件 3 它可以是任何类型的控件 我一般都想这样做 让用户用它做一些触发回发的事情时 它会向

随机推荐