Yes, you can use CPUID.80000008H:EAX[7:0]if supported.
The algorithm is as follows:
- Check the maximum extended value of E for
cpuidwith CPUID.80000000h.EAX. - If E> = 80000008h, use
CPUID.80000008H:EAX[7:0]for the number of bits of physical addresses.
CPUID.80000008H:EAX[15:8]for the number of linear address bits. - Otherwise, if
CPUID.1:EDX.PAE(bit 6), then the CPU has 36 physical address bits and 32 linear address bits. - Otherwise, the CPU has 32 physical and logical address bits.
Intel designation CPUID.X:R Bmeans
- X ,
eax 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;
}
, - 48:39!