为什么在 x86-64 中虚拟地址比物理地址短 4 位(48 位与 52 位长)?

2023-12-10

在《低级编程:英特尔® 64 架构上的 C、汇编和程序执行》一书中,我读到:

每个虚拟 64 位地址(例如,我们在程序中使用的地址) 由几个字段组成。地址本身实际上只有 48 位 宽的;它被符号扩展为 64 位规范地址。它是 特点是其左17位相等。如果条件是 不满意,该地址在使用时会立即被拒绝。然后 48位虚拟地址转换为52位物理地址 在特殊表格的帮助下进行地址处理。

为什么虚拟地址和物理地址相差4位?


我相信你正在谈论x86-64,我的答案是基于该架构的。


当在 64 位模式下运行时,CPU 使用改进的功能将虚拟地址转换为物理地址,称为PAE——物理地址扩展.
该功能最初是为了打破 4GiB 限制而仍然使用 32 位指针而发明的,它涉及使用 4 级表。
每个表都给出一个指向下一个表的指针,一直到最右边的表,该表给出了物理地址的高位。为了得到一个想法,请看这张图片AMD64架构编程手册:

4-Level paging, PAE, in long mode

The rationale behind all those tables is sparsity: the metadata for translating virtual addresses into physical addresses is huge - if we were to use 4KiB pages only we'd need 264 - 12 = 252 entries to cover the whole 64-bit address space.
Tables allow for a sparse approach, only the entries necessary are populated in memory.

这种设计体现在虚拟地址的划分方式上(因此,间接地体现在层数上),仅使用 9 位的运行来索引每一层的表。
从包含的位 12 开始,给出:级别 1 -> 12-20、级别 2 -> 21-29、级别 3 -> 30-38、级别 4 -> 39-47。

这解释了当前虚拟地址空间的实现限制只有 48 位。
请注意,在使用逻辑地址的指令级别,我们完全支持 64 位地址。
分段级别也提供全面支持,该部分将逻辑地址转换为线性地址。
所以限制来自PAE。

My personal观点认为,AMD 急于成为第一个推出支持 64 位的 x86 CPU 的公司,并重用了 PAE,用新的间接级别对其进行了修补,以将其转换为 48 位。
请注意,Intel 和 AMD 都允许未来的实现使用 64 位虚拟地址(可能有更多表)。

然而,两家公司都为物理地址设置了 52 位的硬性限制。 为什么?

答案仍然可以在分页的工作原理中找到。
在32位模式下,每个表中的每个条目都是32位宽;低位用作标志(因为对齐要求使它们对翻译过程无用),但高位全部用于翻译,给出 32/32 虚拟/物理翻译。
需要强调的是,所有 32 位均已使用,而某些较低位未用作标志,英特尔将它们标记为“忽略”或“可用”,这意味着操作系统可以自由使用它们。

当英特尔推出 PAE 时,他们还需要 4 位(当时 PAE 是 36 位),合乎逻辑的做法是double每个条目的大小,因为这会创建比 40 位表条目更有效的布局。
这给了英特尔大量的空闲空间,他们将其标记为保留(这可以在旧版本的英特尔SDM手册中更好地观察到,像这个).

随着时间的推移,条目中需要新的属性,最著名的就是XD/NX钻头.
保护键也是一项相对较新的功能,需要占用条目空间。 这表明当前 ISA 无法再实现完整的 64/64 位虚拟/物理转换。

作为直观参考,以下是 64 位 PAE 表条目的格式:

Intel 64-bit PAE table entries

它表明 64 位物理地址是不可能的(对于大页面,仍然有办法解决这个问题,但考虑到位的布局似乎不太可能),但没有解释为什么 AMD 将限制设置为 52 位。

嗯,这很难说。
当然,物理地址空间的大小也有一定的关系。hardware与之相关的成本:更多的引脚(尽管使用集成内存控制器,由于 DDR 规范复用了大量信号,这一点得到了缓解)以及缓存/TLB 中的更多空间。
在这个question(相似但不足以使其重复)维基百科给出了一个答案,据称该答案又引用了 AMD,声称 AMD 的工程师在适当考虑收益和成本后将限制设置为 52 位。

我分享什么汉斯·帕桑特 写于 6 年多前:当前的分页机制不适合完整的 64 位物理寻址,这可能就是 Intel 和 AMD 从不费心保留每个条目中的高位的原因。

两家公司都知道,随着该技术将接近 52 位限制,它也将与当前的形式有很大不同。
到那时,他们通常会设计出一种更好的记忆机制,因此他们避免了对现有机制的过度设计。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在 x86-64 中虚拟地址比物理地址短 4 位(48 位与 52 位长)? 的相关文章

  • GCC的sqrt()编译后如何工作?使用哪种root方法?牛顿-拉夫森?

    只是对标准感到好奇sqrt 来自 GCC 上的 math h 我自己编码的sqrt 使用牛顿拉夫森来做到这一点 是的 我知道 fsqrt 但CPU是如何做到这一点的呢 我无法调试硬件 现代 CPU 中的典型 div sqrt 硬件使用 2
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 为什么我的代码显示垃圾?

    当我也想打印列表中的每个数字时 我的代码显示垃圾 有什么问题吗 输出应如下所示 给定的数组是 2G 4 PT为什么这是垃圾总数是 7 Code ASSUME CS CODE DS DATA SS STK ORG 0000H DATA SEG
  • 在 x86 汇编中将 64 位常量移至内存

    我正在使用 Intel x64 程序集 NASM 编译器 尝试将 0x4000000000000000 常量移至内存 该常量在 ieee 754 标准双精度中应等于 2 0 我正在使用的代码是 define two 0x4000000000
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 整数溢出问题

    我不断遇到整数溢出问题 我不知道如何解决它 有人可以帮忙吗 edx 包含 181 eax 包含 174 xor eax edx mov edx 2 div edx 假设你谈论的是x86 div edx这实际上没有意义 32位div将edx
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw
  • Grub 和进入实模式(低级汇编语言编程)

    我一直在开发一个玩具操作系统 并一直使用 grub 作为我的引导加载程序 最近尝试使用 VGA 时 我发现无法使用硬件中断 我发现这是因为我被 grub 置于保护模式 有人知道如何在不删除 grub 的情况下回到实模式吗 如果您使用 GRU
  • 一个地址有多少字节? [复制]

    这个问题在这里已经有答案了 在64位机器上 我们知道一个地址是8个字节 然而 我并不完全清楚一个地址中有多少字节的信息 虚拟内存中的每个字节都有一个地址吗 或者内存中的每 64 位都有一个地址 还是取决于架构 如果这取决于架构 那么我应该如
  • Polygot 包含 nasm/yasm 和 C 的文件

    我有一堆幻数 我想将它们包含在由 nasm 或 yasm 编译的 C 程序和汇编文件中 在纯 C 语言中 该文件看起来像是一系列定义 例如 define BLESS 55378008 define ANSWER 42 在 nasm 或 ya
  • 难以理解汇编命令“加载有效地址”[重复]

    这个问题在这里已经有答案了 可能的重复 LEA 指令的目的是什么 https stackoverflow com questions 1658294 whats the purpose of the lea instruction LEA指
  • 嵌入式系统:使用汇编语言时的内存布局

    根据我的理解 嵌入式系统运行机器代码 有多种方法可以生成此代码 一种是用 C 等高级语言编写程序 然后使用编译器获得这样的代码 另一种方法是用汇编语言为该嵌入式系统编写指令 并使用汇编器将其转换为机器代码 现在我们得到了加载到系统并执行的机
  • 编译内核进行页表遍历时出现错误

    我正在执行页表遍历 当我准备更新内核时出现错误 kernel sys c In function do sys get page info kernel sys c 2745 23 error passing argument 1 of p
  • SMP 上如何处理中断?

    SMP 对称多处理器 多核 机器上如何处理中断 内存管理单元是只有一个还是多个 假设两个线程 A 和 B 运行在不同的内核上 同时 访问页表中不存在的内存页面 在这种情况下 将会出现页面错误 并从内存中引入新页面 将会发生的事件的顺序是什么
  • x86 程序集 Pushl/popl 不适用于“错误:后缀或操作数无效”

    我是汇编编程的新手 正在努力解决编程基础 http savannah nongnu org projects pgubook 在带有 GNU 汇编器 v2 20 1 的 Ubuntu x86 64 桌面上 我已经能够汇编 链接执行我的代码
  • 为什么 LED 保持亮起而不是闪烁?

    这是使用 pic16f676 中的 TIMER0 中断使 LED 闪烁的 MPASM 代码 端口 A 的引脚 0 RA0 未切换至关闭位置 请帮忙 我是图片组装的新手 我想掌握图片 有没有高手帮我学习一下 我需要以 1 秒的间隔眨眼 代码是
  • movsbl指令的作用是什么? [复制]

    这个问题在这里已经有答案了 我在网上搜索过 但找不到明确的示例来理解该指令的作用 因此 如果有人可以举一个例子 这对我来说将会非常有帮助 用符号从字节扩展到长字移动 在Intel语法中 该指令的助记符是MOVSX 当变量类型为 C 时 C
  • 测试 xmm/ymm 寄存器是否为零的更快方法?

    It s fortunate that PTEST does not affect the carry flag but only sets the rather awkward ZF also affects both CF and ZF
  • NASM:如何正确访问SSD驱动器?

    我需要使用 NASM 16 位代码访问 SSD 驱动器 访问普通硬盘时 需要设置寄存器AX DX CX来选择柱面 磁道 扇区 扇区数 AH 选择读扇区功能 DL 选择驱动器号 CH 选择气缸 DH 选择磁盘上的一侧 CL 选择步入正轨的部门
  • 如何在 AVX/AVX2 中递增向量

    我想使用内在函数来增加 SIMD 向量的元素 最简单的方法似乎是为每个元素加 1 如下所示 note vec inc之前已设置为1 vec mm256 add epi16 vec vec inc 但是是否有任何特殊指令来增加向量 类似于in

随机推荐

  • 是否有 XSLT 名称元素?

    在 XSLT 中有
  • 无服务器框架 TypeError:e 不是函数

    我在用着serverless framework在 AWS 中安排任务 我的应用程序结构是 src tasks analytics task js tasks js serverless yml 的内容analytics task js m
  • 辅助线程调用主线程的函数

    我正在 PyQt 中制作一个 GUI 供用户创建大量数据的备份 GUI 主线程 正在接受用户的输入 rsync 命令 用于备份 也在主线程中被调用 因此窗口被冻结 目的是尝试 qthread 以便应用程序运行而不会冻结 我的搜索材料 1 h
  • iOS可达性测试

    对于我们的应用程序 每当应用程序用户尝试发布消息时 我们都会使用以下代码来检查互联网连接 当我们测试该功能时 打开飞行模式时它工作正常 那么当我们关闭飞行模式时 对connected的调用仍然返回NO 原因可能是什么 我们是否需要在订单中进
  • 匀称的交叉点与匀称的关系——不精确?

    我想知道我是否以错误的方式思考或者这是否是一个错误 我有一个线串和一个多边形 我创建直线和多边形边界的交点 这些交点应该与多边形的边界相交 至少接触 对吧 from shapely import geometry wkt line geom
  • 什么时候适合使用AJAX?

    什么时候适合使用AJAX 使用 AJAX 的优点和缺点是什么 回答我的最后一个问题 有些人似乎非常坚定地认为我应该只在情况合适的情况下使用 AJAX 我应该将 AJAX 逻辑添加到我的 PHP 类 脚本中吗 回应查德 伯奇的回答 是的 我指
  • 如何在android中的ExpandableListView的getChildView中识别按钮点击

    我正在我的 Android 应用程序中构建 ExpandableListView 我已经制作了重复特定数字的子 xml 布局 我的 xml 布局中有一个删除按钮 其 id 在 xml 中设置为 btnDelete 通过单击删除按钮 我想删除
  • 查找 GitHub Pages 上托管的网站的浏览量 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我已经使用 GitHub Pages 为自己建立了一个网站 但可以知道有多少访问者吗 我知道我的存储库中有流量选项卡 这是否也显示我的网站以及存储库本身的浏览量 如果不是我该怎么办
  • 处理 Altair 分区统计图中的缺失值/空值

    我使用美国州级数据在 Altair 中创建了一张分区统计图 但是 我没有某些州的数据 默认情况下 这些州根本不会出现在地图上 这是一个示例图像 我希望零状态在地图上显示为灰色 Altair 文档显示了另一张符合此描述的地图 我的问题是如何使
  • Android Studio:407 需要代理身份验证

    我已经安装了Android Studio 预览版本 因为稳定的 IDE 版本不支持我的应用程序中使用的 JetPack 但我在同步项目时遇到代理问题 错误 无法获取 https dl google com dl android maven2
  • 如何以编程方式在 iPhone 应用程序中打开 LinkedIn 公司网址?

    我想通过以编程方式打开 LinkedIn 公司网址从我的 iPhone 应用程序到 LinkedIn 应用程序 我正在使用以下代码 但无法正常工作 请帮助我 string NSString stringWithFormat linkedin
  • Python - 从 SQLite3 DB 读取 BLOB 类型

    这是以下内容的后续 Python 将十六进制转换为 INT CHAR 我现在有了一个可行的解决方案 可以将存储的 IP 十六进制值从 sqlite3 数据库转换为可读且可用的格式 然而到目前为止 我一直通过直接从 sqlite3 数据库查看
  • 如何在 DataFlow 作业完成时发出通知

    我想在 GAE 上知道数据流作业何时完成 我尝试制作以下两条管道 1 write to bigquery gt gt beam io WriteToBigQuery WriteStringsToPubSub projects fakeprj
  • Xcode 11.5 无法在运行 iOS13.5 的 iPhone 上安装应用程序

    我正在开发的一个应用程序在我的 iPhone 上运行良好 然后在更新 iOS 后 该应用程序会构建但不会安装到手机上 但可以在模拟器中运行 弹出一条消息 提示无法安装 应用程序名称 我尝试过的 重新安装 Xcode 删除和添加配置文件 重新
  • tkinter - 更改菜单栏位置

    我有一个程序 就像带有教育游戏的桌面环境 我想知道如何将菜单栏放在窗口底部 提前致谢 如果您正在谈论设置时获得的本机菜单栏 则不能menu根窗口的属性 您可以使用框架和一个或多个菜单按钮创建自己的菜单栏 其行为有点像菜单栏 并将其放置在底部
  • Android:如何将动画图像放置在我们可以显示和隐藏的 EditText 中

    我正在尝试添加一个动画微调器inside右侧的 EditText 视图 并以编程方式显示 隐藏它 我通过引入线性插值旋转创建了动画微调器 res anim rotate forever xml
  • javascript 使用 settimeout() 和循环

    我有一个包含 8x10 个单元格的表格 每个销售都有一个具有自己 id 的输入元素 11 12 21 22 23 现在我想在 假设 0 5 秒 之后填充这些输入 我刚刚输入一些值进行测试 Betrag new Array Betrag 0
  • 在 Swarm 重新启动之前,NodeJS 不会检测到 Docker Bind Mount 中的更改

    我正在 Docker 上以 Swarm 模式 单节点 构建 NodeJS 应用程序 我正在为 NodeJS 源代码使用绑定安装卷 一切运行完美 我可以在 localhost 中看到 NodeJS 和 Express 的输出 但是当我更改 N
  • 在 android appwidget 中实现位置侦听器时出现问题

    我正在开发一个小部件 它将获取当前 GPS 位置并将该值传递到远程 PHP 页面以获取信息并将其显示在小部件中 这就是我正在努力做的事情 我在为 appWidget 实现位置侦听器时遇到问题 它没有随当前位置更新 而是显示初始小部件 即 正
  • 为什么在 x86-64 中虚拟地址比物理地址短 4 位(48 位与 52 位长)?

    在 低级编程 英特尔 64 架构上的 C 汇编和程序执行 一书中 我读到 每个虚拟 64 位地址 例如 我们在程序中使用的地址 由几个字段组成 地址本身实际上只有 48 位 宽的 它被符号扩展为 64 位规范地址 它是 特点是其左17位相等