【问题标题】:x86-64: canonical addresses and actual available rangex86-64:规范地址和实际可用范围
【发布时间】:2017-01-17 20:54:17
【问题描述】:

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

是否有标准的方法来以编程方式确定有意义的位数? (即一些特定的 CPUID,就像物理地址一样)。

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

【问题讨论】:

    标签: assembly x86 x86-64 virtual-address-space address-space


    【解决方案1】:

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

    算法如下:

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

    来自英特尔的符号CPUID.X:R B 表示

    • Xcpuid 之前放入eax 的值。
    • R 感兴趣的输出寄存器。
    • B [upper:lower] 格式的位域,或 .bitname 格式的命名位。

    AMD 将 virtual:physical 地址的最大限制设置为 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!

    【讨论】:

      猜你喜欢
      • 2014-11-09
      • 2012-06-30
      • 2014-02-15
      • 2018-01-24
      • 2011-06-28
      • 2014-01-31
      • 1970-01-01
      • 2021-10-06
      • 2022-07-22
      相关资源
      最近更新 更多