只有Pentium III系列CPU才能返回序列号。使用汇编CPUID指令(机器码A20F)来实现。你可以阅读AP-909: Intel Processor Serial Number http://developer.intel.com/design/pentiumiii/applnots/245125.htm 里面有比较详细的介绍,看一下吧!
没那么复杂,直接读注册表就行了 SYSTEM_INFO sysInfo; char str [MAX_PATH]; LONG result; HKEY hKey; TCHAR vendorData [64]; DWORD data; DWORD dataSize; // Get the processor speed info. result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey); // Check if the function has succeeded. if (result == ERROR_SUCCESS) { result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL, (LPBYTE)&data, &dataSize);
m_stCPUSpeed.Format ("%d", data); m_stCPUSpeed += _T (" MHz"); dataSize = sizeof (vendorData); result = ::RegQueryValueEx (hKey, _T("VendorIdentifier"), NULL, NULL, (LPBYTE)vendorData, &dataSize); m_stVendorInfo.Format ("%s", vendorData); } // Make sure to close the reg key RegCloseKey (hKey); // Get the hardware information GetSystemInfo (&sysInfo); // Lets check the processor type first if (sysInfo.dwProcessorType == PROCESSOR_INTEL_386) { m_stProcessorType = _T ("Intel 386"); } else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_486) { m_stProcessorType = _T ("Intel 486"); } else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_PENTIUM) { m_stProcessorType = _T ("Intel Pentium"); } else if (sysInfo.dwProcessorType == PROCESSOR_MIPS_R4000) { // only for NT m_stProcessorType = _T ("MIPS"); } else if (sysInfo.dwProcessorType == PROCESSOR_ALPHA_21064) { // only for NT m_stProcessorType = _T ("Alpha"); } else { m_stProcessorType = _T ("Unknown"); } // check number of processors itoa (sysInfo.dwNumberOfProcessors , str, 10); m_stNumProcessors = CString (str); // Check the architecture type and processor level // Windows 95 doesn't use processor level if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { m_stArchitecture = _T ("Pentium"); switch (sysInfo.wProcessorLevel) { case 3: m_stProcessorLevel = _T ("Intel 80386"); break; case 4: m_stProcessorLevel = _T ("Intel 80486"); break; case 5: m_stProcessorLevel = _T ("Pentium"); // Check if the MMX instruction set is availbale or not. if (IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE)) { m_stProcessorLevel += _T (" MMX"); } break; case 6: m_stProcessorLevel = _T ("Pentium (II/Pro)"); break; } } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_MIPS) { m_stArchitecture = _T ("MIPS"); if (sysInfo.wProcessorLevel == 0004) { m_stProcessorLevel = _T ("MIPS R4000"); } else { m_stProcessorLevel = _T ("Unknown"); } } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA) { m_stArchitecture = _T ("Alpha"); itoa (sysInfo.wProcessorLevel , str, 10); m_stProcessorLevel = m_stArchitecture + CString (str); } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_PPC) { m_stArchitecture = _T ("PPC"); switch (sysInfo.wProcessorLevel) { case 1: m_stProcessorLevel = _T ("PPC 601"); break; case 3: m_stProcessorLevel = _T ("PPC 603"); break; case 4: m_stProcessorLevel = _T ("PPC 604"); break; case 6: m_stProcessorLevel = _T ("PPC 603+"); break; case 9: m_stProcessorLevel = _T ("PPC 604+"); break; case 20: m_stProcessorLevel = _T ("PPC 620"); break; } } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN) { m_stArchitecture = _T ("Unknown"); } // Check page size itoa (sysInfo.dwPageSize , str, 10); m_stPageSize = CString (str); // Application address TCHAR buffer [64]; sprintf( buffer, "%p", sysInfo.lpMaximumApplicationAddress); m_stMaxAddress = _T ("0x") + CString (buffer);
sprintf( buffer, "%p", sysInfo.lpMinimumApplicationAddress); m_stMinAdress = _T ("0x") + CString (buffer); // Get active processor mask // It represent how many processors are active (?? I am not sure) itoa (sysInfo.dwActiveProcessorMask , str, 10); m_stMask = CString (str);
我知道有一个存储着CPU信息的变量:
SYSTEM_INFO sysInfo; //sysInfo是用于存储有关CPU的信息
然后调用函数GetSystemInfo(—sysInfo)得到硬件的有关信息。
你看一下MSDN中的讲解。
/*
用CPUID指令,首先你可以确定你用的CPU是Intel的。
然后执行:
MOV EAX,01H
CPUID
如果返回的EDX中,低18位为1,那么这个CPU就是支持序列号的。
此时EAX就是序列号的高32位。这32位对同一型号的CPU是一样的。
再执行:
MOV EAX,03H
CPUID
此时的EDX:ECX就是序列号的第64位。
要想关闭这个ID,可执行下列代码:MOV ECX,119H
RDMSR
OR EAX,00200000H
WRMSR不过,一旦执行上述代码,cpu将一直不能取id,直到下次reset。*/#include <stdio.h>
#include <conio.h>int main(int argc,char **argv)
{
unsigned long s1,s2;
unsigned char vendor_id[]="------------";
char sel;
printf("Select the function:\n1-------Read CPU id.\n2-------Disable CPU id.\n");
sel=getch();
switch(sel)
{
case '1':
asm xor eax,eax
asm cpuid
asm mov dword ptr vendor_id,ebx
asm mov dword ptr vendor_id[+4],edx
asm mov dword ptr vendor_id[+8],ecx
printf("%s-",vendor_id);
asm mov eax,01h
asm xor edx,edx
asm cpuid
asm mov s1,edx
asm mov s2,eax
printf("%08X\n%08X-",s1,s2);
asm mov eax,03h
asm xor ecx,ecx
asm xor edx,edx
asm cpuid
asm mov s1,edx
asm mov s2,ecx
printf("%08X-%08X\n",s1,s2);
break;
case '2':
asm{
mov ecx,119h
rdmsr
or eax,00200000h
wrmsr
}
printf("CPU id is disabled.\n");
break;
}
return 0;
}最后说一下,那个关闭CPUID的功能我一直也不能成功,总是非法指令。
http://developer.intel.com/design/pentiumiii/applnots/245125.htm
里面有比较详细的介绍,看一下吧!
先让EAX = 0,再调用CPUID
Inel 的CPU 将返回:
EBX:756E6547H 'Genu'
EDX:49656E69H 'ineI'
ECX:6C65746EH 'ntel'
EBX, EDX, ECX 将连成 "GenuineIntel", 真正的Intel。 Cyrix 的CPU 将返回:
EBX:43797269H
EDX:78496E73H
ECX:74656164H
EBX, EDX, ECX 将连成"CyrixInstead",Cyrix来代替。 AMD 的CPU 将返回:
EBX:41757468H
EDX:656E7469H
ECX:63414D44H
EBX, EDX, ECX 将连成"AuthenticAMD",可信的AMD。 (2)CPU等级, 是否支持MMX
先让EAX = 1, 再调用CPUID, EAX 的 8 到11 位就表明是几86
3 - 386
4 - i48
5 - Pentium
6 - Pentium Pro Pentium II
2 - Dual Processors
EDX 的 第0 位: 有无FPU
EDX 的 第23 位: CPU 是否支持IA MMX. (3)专门检测是否 P6 架构(Intel Only)
先让EAX = 1, 再调用CPUID, 如果AL = 1, 就是Pentium Pro 或Pentium II. (4)专门检测AMD 的CPU 信息
先让 EAX = 80000001H,再调用CPUID
如果 EAX = 51H, 是AMD K5
如果 EAX = 66H, 是AMD K6
EDX 第0 位: 是否有FPU( 多余!谁用过没FPU 的K5, K6?)
EDX 第23 位,CPU是否支持MMX. 程序示例: int main(int argc, char **argv)
{
char OEMString[13];
int iEAXValue, iEBXValue, ECXValue, iEDXValue; _asm
{
mov eax,0
cpuid
mov DWORD PTR OEMString,ebx
mov DWORD PTR OEMString+4,edx
mov DWORD PTR OEMString+8,ecx
mov BYTE PTR OEMString+12,0
} cout << "This CPU's OEM String is:" << OEMString << endl; _asm
{
mov eax,1
cpuid
mov iEAXValue, eax
mov iEBXValue, ebx
mov iECXValue, ecx
mov iEDXValue, edx
} if(iEDXValue & 0x800000)
{
cout << "This CPU support MMX" << endl;
}
else
{
cout << "This CPU NOT support MMX" << endl;
} int iCPUFamily = (0x0F00 & iEAXValue) >> 8;
cout << "CPU Familyis:" << iCPUFamily << endl; _asm
{
mov eax, 2
CPUID
} if(_AL == 1)
{
cout << "Pentium Pro or Pentium II Found";
} getch();
return 0;
}
http://www.codeproject.com/system/camel.asp支持的东西很多 支持的系统更多 不过都是windows的 :)Supports Microsoft® Windows™ From:
Windows™ 95 / 95 OSR2 / 95 OSR2.5
Windows™ 98 / 98 SE
Windows™ Millennium
Windows™ NT 3.51
Windows™ NT 4.0 Workstation / Server [Including SP1 to SP6a]
Windows™ 2000 Workstation / Server / Advanced Server / Datacenter Server (Including SP1 to SP3)
Windows™ XP Personal / Professional [Including SP1]
Windows™ .NET Web Server / Standard Server / Enterprise Server
Supports Processors From:
Intel / AMD / Cyrix / Rise / UMC / IDT / Transmeta / NexGen / National Semiconductor See Camel.txt for processor listings... E.g. Pentium III "Coppermine" or Athlon XP 1800+ (Thoroughbred Core).
Detects Hardware Features:
Processor hardware
Single Processors
Dual Processors
Multiple Processors
HyperThreading Technology
Serial Number [if enabled]
On-Chip APIC Hardware
Hard-Coded Chip Names
L1 Cache Size
L2 Cache Size
L3 Cache Size
CPU Clock Speed [of each processor]
Thermal Monitioring Support
ACPI Support
On-Chip PowerManagement [SpeedStep, etc.]Multimedia Instruction Sets
MMX
MMX+
Streaming SIMD Extensions
Streaming SIMD Extensions [Floating Point]
Streaming SIMD Extensions [MMX]
Streaming SIMD Extensions 2
3DNow!
3DNow!+General Instruction Sets
Floating Point Unit [FPU]
Time Stamp Counter [TSC]
Conditional Move [CMOV]
Memory Type Range Registers [MTRR]
{
CComBSTR bstr("");
char szCPUID[129] = {NULL};
char szTmp[33] = {NULL};
unsigned long s1 = 0,
s2 = 0;
_asm
{
mov eax,01h
xor edx,edx
cpuid
mov s1,edx
mov s2,eax
}
sprintf(szTmp, "%08X%08X", s1, s2);
strcpy(szCPUID, szTmp);
_asm
{
mov eax,03h
xor ecx,ecx
xor edx,edx
cpuid
mov s1,edx
mov s2,ecx
}
sprintf(szTmp, "%08X%08X", s1, s2);
strcat(szCPUID, szTmp);
bstr = szCPUID; *bstrCPUID = bstr.Copy(); return S_OK;
}
SYSTEM_INFO sysInfo;
char str [MAX_PATH];
LONG result;
HKEY hKey;
TCHAR vendorData [64];
DWORD data;
DWORD dataSize; // Get the processor speed info. result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE,
"Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey); // Check if the function has succeeded. if (result == ERROR_SUCCESS) {
result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL,
(LPBYTE)&data, &dataSize);
m_stCPUSpeed.Format ("%d", data);
m_stCPUSpeed += _T (" MHz"); dataSize = sizeof (vendorData); result = ::RegQueryValueEx (hKey, _T("VendorIdentifier"), NULL, NULL,
(LPBYTE)vendorData, &dataSize); m_stVendorInfo.Format ("%s", vendorData);
} // Make sure to close the reg key RegCloseKey (hKey); // Get the hardware information GetSystemInfo (&sysInfo); // Lets check the processor type first if (sysInfo.dwProcessorType == PROCESSOR_INTEL_386) {
m_stProcessorType = _T ("Intel 386");
}
else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_486) {
m_stProcessorType = _T ("Intel 486");
}
else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_PENTIUM) {
m_stProcessorType = _T ("Intel Pentium");
}
else if (sysInfo.dwProcessorType == PROCESSOR_MIPS_R4000) {
// only for NT
m_stProcessorType = _T ("MIPS");
}
else if (sysInfo.dwProcessorType == PROCESSOR_ALPHA_21064) {
// only for NT
m_stProcessorType = _T ("Alpha");
}
else {
m_stProcessorType = _T ("Unknown");
} // check number of processors itoa (sysInfo.dwNumberOfProcessors , str, 10); m_stNumProcessors = CString (str); // Check the architecture type and processor level // Windows 95 doesn't use processor level if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
m_stArchitecture = _T ("Pentium");
switch (sysInfo.wProcessorLevel) {
case 3:
m_stProcessorLevel = _T ("Intel 80386");
break;
case 4:
m_stProcessorLevel = _T ("Intel 80486");
break;
case 5:
m_stProcessorLevel = _T ("Pentium");
// Check if the MMX instruction set is availbale or not. if (IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE)) {
m_stProcessorLevel += _T (" MMX");
}
break;
case 6:
m_stProcessorLevel = _T ("Pentium (II/Pro)");
break;
}
}
else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_MIPS) {
m_stArchitecture = _T ("MIPS");
if (sysInfo.wProcessorLevel == 0004) {
m_stProcessorLevel = _T ("MIPS R4000");
}
else {
m_stProcessorLevel = _T ("Unknown");
}
}
else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA) {
m_stArchitecture = _T ("Alpha"); itoa (sysInfo.wProcessorLevel , str, 10); m_stProcessorLevel = m_stArchitecture + CString (str);
}
else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_PPC) {
m_stArchitecture = _T ("PPC"); switch (sysInfo.wProcessorLevel) {
case 1:
m_stProcessorLevel = _T ("PPC 601");
break;
case 3:
m_stProcessorLevel = _T ("PPC 603");
break;
case 4:
m_stProcessorLevel = _T ("PPC 604");
break;
case 6:
m_stProcessorLevel = _T ("PPC 603+");
break;
case 9:
m_stProcessorLevel = _T ("PPC 604+");
break;
case 20:
m_stProcessorLevel = _T ("PPC 620");
break;
}
}
else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN) {
m_stArchitecture = _T ("Unknown");
}
// Check page size itoa (sysInfo.dwPageSize , str, 10);
m_stPageSize = CString (str); // Application address TCHAR buffer [64]; sprintf( buffer, "%p", sysInfo.lpMaximumApplicationAddress); m_stMaxAddress = _T ("0x") + CString (buffer);
sprintf( buffer, "%p", sysInfo.lpMinimumApplicationAddress); m_stMinAdress = _T ("0x") + CString (buffer); // Get active processor mask
// It represent how many processors are active (?? I am not sure) itoa (sysInfo.dwActiveProcessorMask , str, 10);
m_stMask = CString (str);