author : 辟邪马甲
本节介绍CPU技术特征的获取方法
关于CPU这方面的信息,如果你有IA32的文档就会有很多有意思的发现,
具体请参考第二卷,指令集中的CPUID指令 . 在vc里采用嵌套asm指令的方法来执行该指令.
{
// The following 4 DWORD variable store the four registers values after cpuid
DWORD deax;
DWORD debx;
DWORD decx;
DWORD dedx;
__asm
{
mov eax, veax
cpuid //指令
mov deax, eax
mov debx, ebx
mov decx, ecx
mov dedx, edx
}
}


不要小看这么一条小小的指令,很多内在的信息都是通过执行该指令而获得
EAX是做为指令输入参数的,
不同EAX的初始值执行后得到的EAX,EBX,ECX,EDX四个寄存器的值和对应的技术规格也是不同的.
我们来具体看一下:
Initial EAX Value //EAX初始值
经过上面几张图表我们就可以很清晰的知道每个参数以及对应的返回值所代表的具体规格!
其中,技术特征规格如下
EAX:01H
EAX Version Information: Type, Family, Model, and Stepping ID 
EBX Bits 7-0: Brand Index
Bits 15-8: CLFLUSH line size
Bits 23-16: Maximum number of logical processors in this physical package.
Bits 31-24: Initial APIC ID
ECX Extended Feature Information 
EDX Feature Information 



这里ECX,EDX里面放的就是对应的技术特征信息了
这两个寄存器的每个BIT对应的详细技术特征如下
到目前为止,应该是很清楚的了!
Exemple:
如果 返回值 DWORD dwEDX;
内建浮点运算协处理器(FPU) 对应的是第0位
if ( (dwEdx & (0x0000001)) == 0x00000001 )
...{
.....SUPPORT;
}
else
.....NONSUPPORT;Intel MMX(MMX) BIT 23
超线程技术(HTT) BIT 28

if ( (dwEdx & (1 << 23)) == 0x800000 )
...{
SUPPORT;
}
else
NONSUPPORT;
if ( (dwEdx & (1 << 28)) == 0x10000000 )
...{
SUPPORT;
}
else
NONSUPPORT;
并且ECX寄存器中也存储了一部分技术特征.
同时我们也可以得到 CPU的 Vender ID String:
EAX:00H
char cVID[13]; // Store Vender ID String, contain 12 chars
memset(cVID, 0, 13); //
Executecpuid(0); // Execute cpuid instruction with eax = 0
memcpy(cVID, &m_ebx, 4); // ebx contains the first 4 chars
memcpy(cVID+4, &m_edx, 4); // edx contains the middle 4 chars
memcpy(cVID+8, &m_ecx, 4); // ecx contains the last 4 chars;获得CPU Brand数据
EAX = 0x80000002 ----- 0x80000004
const DWORD BRANDID = 0x80000002; // brand parameter start at 0x80000002
char cBrand[49]; // Store Brand String, contain 48 chars
memset(cBrand, 0, 49); // Initialize all chars to 0
for (DWORD i = 0; i < 3; i++) // Execute cpuid instruction with 
...{ // eax = 0x80000002 to 0x80000004
Executecpuid(BRANDID + i);
memcpy(cBrand + i*16, &m_eax, 16); // eax, ebx, ecx, edx contain the brand string
}
return CString(cBrand);
获得CPU的 SerialNumber 注意下,这个数据有的型号的CPU是没有的,所以你得到个0并不能说明什么

struct SerialNumber
...{
WORD nibble[6]; // 6 WORD nibble;
SerialNumber() //constructor
...{
memset(nibble, 0, sizeof(nibble));
}
};



Executecpuid(1); // Execute cpuid instruction with eax = 1
bool isSupport = m_edx & (1<<18); // Check if Serial Number is supported
if (false == isSupport) // not support
...{
return false;
}
memcpy(&serial.nibble[4], &m_eax, 4); // eax is the higher 2 nibble
Executecpuid(3); // Execute cpuid instruction with eax = 3
memcpy(&serial.nibble[0], &m_ecx, 8); // ecx and edx constains the middle and first 4 nibble
还有其他一些信息就不一一列举了,
总之我们可以看到这么一条小小指令,
几乎吧整个CPU的信息都挖出来了!
因此,让我们记住这条强悍的指令 CPUID
(更多,更详细的资料请参考IA32 第二卷 CPUID指令的详细说明)

被折叠的 条评论
为什么被折叠?



