x86-64:规范地址和实际可用范围 [英] x86-64: canonical addresses and actual available range
问题描述
Intel和AMD文档说,对于64位模式,实际上只有48位可用于虚拟地址,并且从48到63的位必须复制第47位(符号扩展).据我所知,目前所有的CPU都是以这种方式实现的,但是从理论上讲,没有任何事情可以扩展以后的实现中的可用空间(这不会破坏二进制兼容性).
Intel and AMD documentation says that for 64 bit mode only 48 bits are actually available for virtual addresses, and bits from 48 to 63 must replicate bit 47 (sign-extension). As far as I know, all current CPU are implemented this way, but nothing (in theory) forbids to extend the available space in future implementations (and this won't break the binary compatibility).
是否存在一种标准方式以编程方式确定有意义的位数? (即某些特定的CPUID,就像物理地址一样).
Is there a standard way to programatically determine the number of meaningful bits? (i.e. some specific CPUID, as happens for physical addresses).
我知道实际上48位对于任何合理的应用程序和OS来说已经绰绰有余;我的问题是理论上的.
I know that in practice 48 bits are far more than enough for any reasonable application and OS; my question is theoretical.
推荐答案
是的,如果支持,可以使用CPUID.80000008H:EAX[7:0]
.
Yes, you can use CPUID.80000008H:EAX[7:0]
if supported.
算法如下:
- 用
CPUID.80000000h.EAX
检查cpuid
的最大扩展 E 值. - 如果 E > = 80000008h,请使用
CPUID.80000008H:EAX[7:0]
表示物理地址位数.
CPUID.80000008H:EAX[15:8]
表示线性地址位数. - 否则,如果
CPUID.1:EDX.PAE
(位6),则CPU具有36个物理地址位和32个线性地址位. - 否则,CPU具有32个物理和逻辑地址位.
- Check the maximum extended E value for
cpuid
withCPUID.80000000h.EAX
. - If E >= 80000008h, use
CPUID.80000008H:EAX[7:0]
for the number of physical address bits.
CPUID.80000008H:EAX[15:8]
for the number of linear address bits. - Else if
CPUID.1:EDX.PAE
(bit 6) then the CPU has 36 physical address bits and 32 linear address bits. - Else the CPU has 32 physical and logical address bits.
Intel的符号CPUID.X:R B
表示
- X 在
cpuid
之前放入eax
的值. - R 感兴趣的输出寄存器.
- B 格式为 [upper:lower] 的位域,或格式为 .bitname 的命名位.
- X The value to put into
eax
beforecpuid
. - R The output register of interest.
- B A bitfield in the form [upper:lower] inclusive, or a named bit in the form .bitname.
AMD将 virtual:physical 地址的最大限制设置为63:52.
尽管物理地址空间的大小可以不同,但是当前的实现通常是48:40.
AMD set the maximum limits for virtual:physical addresses at 63:52.
The current implementation is typically 48:40, though the size of the physical address space can be different.
可以用NASM编译的示例代码
An example code that can be compiled with 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!
And I've just discovered that my Haswell is a 48:39!
这篇关于x86-64:规范地址和实际可用范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!