我再强调一遍,并不是所有的处理器都有序列号!Intel的文档告诉我们Pentium 4 系列的处理器不支持序列号!经过测试发现AMD的机器也没有,奇郁闷,看来这个Processor Serial Number实在用处不大了。然则研究了这么久,还是贴出来吧,兴许有人能用上喔。
文档告诉我们CPU SN是一个96bit的串,可以通过调用汇编指令cpuid获取,具体怎么获取看代码吧。才二三十行呢,呵呵。
这里可以下到完整版的文档:
Intel Processor Identification and the CPUID Instruction
以下是Intel文档中关于Processor Serial Number的部分。
A. Presence of Processor Serial Number
To determine if the processor serial number feature is supported, the program should set the EAX
register parameter value to “1” and then execute the CPUID instruction as follows:
MOV EAX, 01H
CPUID
After execution of the CPUID instruction, the ECX and EDX register contains the Feature Flags.
If the PSN Feature Flags, (EDX register, bit 18) equals “1”, the processor serial number feature is
supported, and enabled. If the PSN Feature Flags equals “0”, the processor serial number
feature is either not supported, or disabled.
B. Forming the 96-bit Processor Serial Number
The 96-bit processor serial number is the concatenation of three 32-bit entities.
To access the most significant 32-bits of the processor serial number the program should set the
EAX register parameter value to “1” and then execute the CPUID instruction as follows:
MOV EAX, 01H
CPUID
After execution of the CPUID instruction, the EAX register contains the Processor Signature. The
Processor Signature comprises the most significant 32-bits of the processor serial number. The
value in EAX should be saved prior to gathering the remaining 64-bits of the processor serial
number.
To access the remaining 64-bits of the processor serial number the program should set the EAX
register parameter value to “3” and then execute the CPUID instruction as follows:
MOV EAX, 03H
CPUID
After execution of the CPUID instruction, the EDX register contains the middle 32-bits, and the
ECX register contains the least significant 32-bits of the processor serial number. Software may
then concatenate the saved Processor Signature, EDX, and ECX before returning the complete 96-
bit processor serial number.
Processor serial number should be displayed as 6 groups of 4 hex nibbles (Ex. XXXX-XXXXXXXX-
XXXX-XXXX-XXXX where X represents a hex digit). Alpha hex characters should be
displayed as capital letters.
以下是获取CPU序列号的代码
void ToHex(const unsigned char * szOrigin, int nSize, char * szHex)
{
char szTemp[10];
for(int nIndex = 0; nIndex < nSize; nIndex ++)
{
sprintf(szTemp, "%02X", szOrigin[nIndex]);
if(nIndex == 0)
{
strcpy(szHex, szTemp);
}
else
{
strcat(szHex, szTemp);
}
}
}
bool DetectCPU()
{
char szCPUDesc[13];
memset(szCPUDesc, 0, 13);
unsigned char szCPUSN[12];
memset(szCPUSN, 0, 12);
unsigned long ulEAX = 0U, ulEBX = 0U, ulECX = 0U, ulEDX = 0U;
__try
{
_asm
{
mov eax, 1
cpuid
mov ulEDX, edx
mov ulEAX, eax
}
//检查是否有CPU序列号
//注意,Intel文档中说检测edx的第18位是从第0位开始计算的
if(!(ulEDX & (1 << 18)))
return false;
//获取序列号的后两个WORD
memcpy(&szCPUSN[8], &ulEAX, 4);
_asm
{
mov eax, 3
cpuid
mov ulECX, ecx
mov ulEDX, edx
}
//获取序列号的前4个WORD
memcpy(&szCPUSN[0], &ulECX, 4);
memcpy(&szCPUSN[4], &ulEDX, 4);
//获取CPU OEM信息
_asm
{
mov eax, 0
cpuid
mov dword ptr szCPUDesc[0], ebx
mov dword ptr szCPUDesc[4], edx
mov dword ptr szCPUDesc[8], ecx
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
char szCPUSNHex[25];
ToHex(szCPUSN, 12, szCPUSNHex);
char szCPUID[37];
sprintf(szCPUID, "%s%s", szCPUDesc, szCPUSNHex);
return true;
}