是的,您可以使用CPUID.80000008H:EAX[7:0]
如果支持的话。
算法如下:
- 检查最大扩展E价值
cpuid
with CPUID.80000000h.EAX
.
- If E>= 80000008h,使用
CPUID.80000008H:EAX[7:0]
为物理地址位数。
CPUID.80000008H:EAX[15:8]
为线性地址位数。
- Else if
CPUID.1:EDX.PAE
(位6)则CPU有36个物理地址位和32个线性地址位。
- 否则,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!