x86-64:规范地址和实际可用范围

2023-12-09

Intel 和 AMD 文档称,对于 64 位模式,实际上只有 48 位可用于虚拟地址,并且从 48 到 63 的位必须复制位 47(符号扩展)。据我所知,当前所有的CPU都是以这种方式实现的,但是(理论上)没有什么禁止在未来的实现中扩展可用空间(并且这不会破坏二进制兼容性)。

是否有一种标准方法可以以编程方式确定有意义的位数? (即某些特定的 CPUID,如物理地址所示)。

我知道实际上 48 位对于任何合理的应用程序和操作系统来说都绰绰有余;我的问题是理论上的。


是的,您可以使用CPUID.80000008H:EAX[7:0]如果支持的话。

算法如下:

  1. 检查最大扩展E价值cpuid with CPUID.80000000h.EAX.
  2. If E>= 80000008h,使用CPUID.80000008H:EAX[7:0]为物理地址位数。
    CPUID.80000008H:EAX[15:8]为线性地址位数。
  3. Else if CPUID.1:EDX.PAE(位6)则CPU有36个物理地址位和32个线性地址位。
  4. 否则,CPU 有 32 个物理和逻辑地址位。

来自英特尔的符号,CPUID.X:R B means

  • X投入的价值eax before cpuid.
  • R感兴趣的输出寄存器。
  • B表单中的位域[上:下]包含在内,或形式中的命名位.bitname.

AMD 设置了最大限制虚拟:物理63:52 发表讲话。
当前的实现通常为 48:40,但物理地址空间的大小可能不同。


可以使用 NASM 编译的示例代码

BITS 64

GLOBAL max_phy_addr
GLOBAL max_lin_addr


SECTION .text


max_phy_addr:
 push rbx


 mov eax, 80000000h
 cpuid

 cmp eax, 80000008h
 jae .fromCpuid

 mov eax, 1
 cpuid

 mov eax, 32
 shr edx, 4
 and edx, 4

 add eax, edx

 pop rbx
 ret

.fromCpuid:

 mov eax, 80000008h
 cpuid

 movzx eax, al

 pop rbx
 ret


max_lin_addr:
 push rbx

 mov eax, 80000000h
 cpuid

 cmp eax, 80000008h
 jae .fromCpuid

 mov eax, 1
 cpuid

 mov eax, 32

 pop rbx
 ret

.fromCpuid:

 mov eax, 80000008h
 cpuid

 movzx eax, ah

 pop rbx
 ret

并与 C 程序一起使用,例如

#include <stdio.h>

long max_phy_addr();
long max_lin_addr();

int main()
{
   printf("Phy: %llu\nLin: %llu\n", max_phy_addr(), max_lin_addr());
   return 0;
}

我刚刚发现我的 Haswell 是 48:39!

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

x86-64:规范地址和实际可用范围 的相关文章

  • FreePascal x64 上系统单元函数的汇编调用

    我有一些 Delphi 汇编代码 可以在 Win32 Win64 和 OSX 32 上编译并正常工作 XE2 但是 由于我需要它在 Linux 上工作 所以我一直在考虑编译它的 FPC 版本 到目前为止 Win32 64 Linux32 6
  • 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

    我正在看维基百科页面 https en wikipedia org wiki Call stack在调用堆栈上 并尝试理解这个图像 据我所知 哈哈 const memory memory 0 3 top of stack pointer m
  • 这种没有推送寄存器的交换有多安全?

    我对汇编非常陌生 下面的代码应该通过两个不同的函数交换两个整数 首先使用swap c然后使用swap asm 但我怀疑 我是否需要push 我的意思是保存 汇编代码之前寄存器的每个值和pop稍后 就在返回之前 main 换句话说 如果我返回
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • NASM 中的 equ 和 db 有什么区别?

    len equ 2 len db 2 它们是否相同 产生可以用来代替的标签2 如果不是 那么每种申报表的优点或缺点是什么 它们可以互换使用吗 第一个是equate 与 C 类似 define len 2 因为它实际上并没有在最终代码中分配任
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • SIMD 和 VLIW 指令是一样的吗?

    SIMD 单指令多数据 和 VLIW 超长指令字 到底有什么区别 其中一个是另一个的子集吗 或者它们是两个完全不同的东西 完全不相关且正交 一台机器可以有一个或两个 或者两者都没有 SIMD 指令可以作为扩展添加到 VLIW ISA 但 V
  • 为什么X86中没有NAND、NOR和XNOR指令?

    它们是您可以在计算机上执行的最简单的 指令 之一 它们是我亲自实施的第一个指令 执行 NOT AND x y 会使执行时间和依赖链长度和代码大小加倍 BMI1 引入了 andnot 这是一个有意义的补充 是一个独特的操作 为什么不是这个问题
  • movzbl(%rdi, %rcx, 1), %ecx 在 x86-64 汇编中意味着什么?

    我想我明白 movzbl rdi rcx 1 ecx 意思是 将零扩展字节移至长整型 并表示将 ecx 扩展为 32 位 但我不完全确定语法 rdi rcx 1 指的是什么 我在某处看到该语法指的是 Base Index Scale 但我找
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • 调用可以是 cdecl 或 stdcall 的函数

    我需要编写调用外部函数的代码 该函数可以是 32 位 Windows 应用程序中的 stdcall 调用或 cdecl 我的代码 调用者 无法提前知道其中的哪一个 现在 如果我尝试从定义为 stdcall 的调用站点调用 cdecl 函数
  • PAE(物理地址扩展)如何实现大于4GB的地址空间?

    维基百科文章的摘录物理地址扩展 http en wikipedia org wiki Physical Address Extension x86 处理器硬件架构通过用于选择附加内存的附加地址线进行了增强 因此物理地址大小从 32 位增加到
  • x86 LargeAddressAware 兼容性的单元测试

    对于 win32 可执行文件 x86 我们可以设置 LargeAddressAware 标志 以便它在 x64 Windows 上运行时可以访问 4 GB 而不是仅 2 GB 的虚拟地址空间 这看起来很吸引人 然而 这也存在风险 例如参见
  • 将 C 代码转换为 x86-64 汇编

    我正在尝试将 C 代码转换为 x86 64 我的目标是反转链表 传入的两个参数是 head ptr 和 offset to 以获取指针字段的地址 即指向列表中下一个节点的指针 据我了解 head ptr是通过rdi寄存器传入的 offset
  • 在 Intel x86 架构上使用非 AVX 指令移动 xmm 整数寄存器值

    我有以下问题 需要使用 AVX2 以外的任何工具来解决 我有 3 个值存储在 m128i 变量中 不需要第四个值 需要将这些值移动 4 3 5 我需要两个功能 一个用于按这些值进行右逻辑移位 另一个用于左逻辑移位 有谁知道使用 SSE AV
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • 如何有效地扫描每次迭代交替的 2 位掩码

    给定 2 个位掩码 应交替访问 0 1 0 1 我尝试获得运行时高效的解决方案 但找不到比以下示例更好的方法 uint32 t mask 2 uint8 t mask index 0 uint32 t f tzcnt u32 mask ma
  • long double(GCC 特定)和 __float128

    我正在寻找有关的详细信息long double and float128在 GCC x86 中 更多是出于好奇而不是因为实际问题 可能很少有人需要这些 我只是有史以来第一次 truly需要一个double 但我想知道你的工具箱里有什么以及它
  • 无法在 64 位 Linux 上从汇编 (yasm) 代码调用 C 标准库函数

    我有一个函数foo以汇编语言编写 并在 Linux Ubuntu 64 位上使用 yasm 和 GCC 编译 它只是使用以下命令将消息打印到标准输出puts 如下所示 bits 64 extern puts global foo secti

随机推荐

  • JS:在文本中查找 URL,创建链接

    下面用 JS 重写的 PHP 代码是什么 以便文本 blob 内的 url 链接可以替换为 html 链接 我已经开始了jsfiddle
  • 更改PIL模块中的图像颜色

    我正在尝试改变颜色的强度以获得不同颜色的图像 import PIL from PIL import Image from PIL import ImageEnhance from PIL import ImageDraw read imag
  • 如何禁止从 Angular JS 下拉列表中选择特定选项?

    我想从 AngularJS 下拉列表中禁用特定选项 它应该列在下拉列表中 但不应允许选择它 所以我需要禁用它 我的文件 tpl html
  • 重复本地通知不更新内容

    我制作了一个应用程序 每天上午 9 点发送一条本地通知 向用户显示随机素数 问题是显示的数字始终相同 创建通知请求的代码仅被调用一次 这是我所期望的 因为通知是重复的 那么我如何更新其内容 我可以提供生成随机素数的代码 但我已经测试过它并且
  • 使用 Ivy Bridge 和 Haswell 循环展开以实现最大吞吐量

    我正在使用 AVX 同时计算八个点积 在我当前的代码中 我做了这样的事情 在展开之前 常春藤桥 桑迪桥 m256 areg0 mm256 set1 ps a m for int i 0 i
  • 确定字符串是否具有唯一字符

    该问题要求 实现一种算法来确定字符串是否具有所有唯一字符 我看到了解决方案 但不太明白 public boolean isUniqueChars String str if str length gt 256 return false bo
  • 如何在 R 中为 dist 函数指定其他方法?

    在 R 中 dist 函数的文档中有以下内容 method 要使用的距离测量 这必须是 euclidean maximum manhattan canberra binary 或 minkowski 之一 可以给出任何明确的子字符串 但我需
  • 如何删除 woocommerce 添加的购物车项目并重定向到结帐?

    我有一个用于 添加资金 的 Woocommerce 表格 它有一个金额输入字段 20 美元 30 美元 等 和一个提交按钮 该按钮重定向到购物车页面 其中输入的金额为总计 重定向到结账正常 但如果用户放弃购物车并尝试再次订购 则购物车商品不
  • 移动圆弧上出现半径线

    我试图创建这些移动的形状 该形状由半圆形和对称的上弧和下弧组成 它们应该只是前面的形状 但现在当它们移动时 后面会拖着一条像尾巴一样的线 尾部未知的输出形状 这些线似乎来自上下弧的 moveTo 部分 但我不知道如何解决它 我应该在哪里改变
  • 在 WPF 中将像素转换为 CM

    I have New System Windows LengthConverter ConvertFrom 1cm 37 795275590551178 Double Double 37 795275590551178 So in 1cm
  • 我们如何使用资产目录颜色集?

    我通常使用 Swift 扩展在 iOS 上使用自定义 UIColor 但现在使用 iOS 11 Xcode 9 我们可以创建颜色集 我们如何使用它们 更新 提示 正如 C ur 所说 我们可以拖放颜色 并将其用作 UIColor 对象 可能
  • 在 Cordova 插件中使用 iBeacons,即在活动/服务之外

    我正在尝试编写一个 Cordova 插件 它与 Android 的 Radius Networks iBeacon 库进行交互 现在 我知道该库是为与活动 服务一起使用而设计的 但这在我的情况下不起作用 因此我正在尝试根据文档尽可能地调整它
  • C# 解析文本文件并将值存储在数组中

    我正在尝试将具有以下格式的文本文件读入数组 Previous errors were for Test id 1234567 Error id 12345678 Previous errors were for Test id 123456
  • 如何清除实体框架中跟踪的实体

    我正在运行一些在一大堆实体上运行的修正代码 随着它的进展 速度会降低 这是因为上下文中跟踪的实体数量随着每次迭代而增加 这可能需要很长时间 所以我在最后保存更改每次迭代的 每次迭代都是独立的 不会更改先前加载的实体 我知道我可以关闭更改跟踪
  • 从 C# 调用托管 C# COM 对象

    我正在尝试从 C 调用 C COM 对象 我用 C 创建了一个类库 并使用 tlbexe exe 导出了一个类型库 然后我使用 regtlibv12 exe 注册了类型库 但是 当我在 Visual Studio 中添加对 COM 对象的引
  • 使用 array_search 进行多维数组

    在一维数组中使用 array search 很简单 array array apple banana cherry searchValue cherry key array search searchValue array echo key
  • 如何在R编程中读取和解码二维码图像? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 如何在R编程中读取和解码二维码图像 我想将带有二维码的图像转换为文本 R 有用于生成 QR 码的库 如 package qrcode 和 packa
  • eclipse 中junit 的等宽字体?

    如何更改 JUnit 选项卡中的字体 以便它使用等宽字体显示结果 我正在使用 Groovy 我找到了解决方案here 您需要转到 Groovy gt Preferences 并选中使用等宽字体复选框
  • ag-grid v 22.1.1 升级后 ng build --prod 失败

    我已经开始使用ag grid从版本 18 开始 目前为 20 0 0 我正在升级到最新版本 22 1 1 解决由于重大更改而导致的警告 错误后 一切 包括 ng服务 都工作正常 但是 当我尝试在产品模式下构建角度应用程序时 它失败了 app
  • x86-64:规范地址和实际可用范围

    Intel 和 AMD 文档称 对于 64 位模式 实际上只有 48 位可用于虚拟地址 并且从 48 到 63 的位必须复制位 47 符号扩展 据我所知 当前所有的CPU都是以这种方式实现的 但是 理论上 没有什么禁止在未来的实现中扩展可用