主题:全面获取CPU信息
■ 全面获取CPU信息
————————————————以下为程序代码—————————————
———————————— 一、获取CPU厂家信息————————————
Const
CPUVendorIDs :array[0..5] of string = ('GenuineIntel','UMC UMC UMC','AuthenticAMD','CyrixInstead','NexGenDriven','CentaurHauls');
//将CPU厂家信息转换成字串形式
CPUVendors :array[0..5] of string = ('Intel','UMC','AMD','Cyrix','NexGen','CentaurHauls');
type TVendor = array [0..11] of char;
// 获取CPU厂家信息,返回值为TVendor类型
function GetCPUVendor : TVendor; assembler; register;
asm
PUSH EBX
PUSH EDI
MOV EDI,EAX
MOV EAX,0
DW $A20F //CPUID指令
MOV EAX,EBX
XCHG EBX,ECX
MOV ECX,4
@1:
STOSB
SHR EAX,8
LOOP @1
MOV EAX,EDX
MOV ECX,4
@2:
STOSB
SHR EAX,8
LOOP @2
MOV EAX,EBX
MOV ECX,4
@3:
STOSB
SHR EAX,8
LOOP @3
POP EDI
POP EBX
end;
调用方式:
var
Vendor: string;
VendorID, I: integer;
begin
Vendor := GetCPUVendor;
for i := 0 to High(CPUVendorIDs) do
begin
If Vendor = CPUVendorIDs[I] then
begin
Vendor := CPUVendors[I]; //把厂家信息精简一下,好看多了
VendorID := i;
break;
end;
end;
end;
———————————— 二、获取CPU类型信息 ————————————
const ID_BIT=$200000; //CPU ID 位标记
type TCPUID=array[1..4] of Longint;
//判断CPUID信息是否有效
function IsCPUIDAvailable : Boolean; register;
asm
PUSHFD //不允许直接存取,必须通过堆栈
POP EAX
MOV EDX,EAX
XOR EAX,ID_BIT
PUSH EAX
POPFD
PUSHFD
POP EAX
XOR EAX,EDX //检测ID位是否受影响
JZ @exit //CPUID无效
MOV AL,True //CPUID无效
@exit:
end;
//获取CPUID信息,返回值为TCPUID类型
function GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX
PUSH EDI
MOV EDI,EAX
MOV EAX,1
DW $A20F //CPUID指令
STOSD //CPUID[1]
MOV EAX,EBX
STOSD //CPUID[2]
MOV EAX,ECX
STOSD //CPUID[3]
MOV EAX,EDX
STOSD //CPUID[4]
POP EDI
POP EBX
end;
具体使用方法:
const
CPUSubModels: array[0..4] of string = ('Primary','OverDrive','Secondary','Reserved','Not Detected');
var
CPUID: TCPUID;
SubModel: string;
SubModelID, Family, Model, Stepping: Integer;
begin
//如果CPUID信息有效
if IsCPUIDAvailable then
begin
fillchar(CPUID, sizeof(CPUID), -1);
CPUID := GetCPUID;
SubModelID := CPUID[1] shr 12 and 3;
Family := CPUID[1] shr 8 and $F;
Model := CPUID[1] shr 4 and $F;
Stepping:= CPUID[1] and $F;
if SubModelID < 4 then
SubModel := CPUSubModels[SubModelID]
else
SubModel := CPUSubModels[4];
end;
end;
——————由所获取的信息,可在下表中找出相应的CPU类型————————
Family VendorID Model CPU类型
4 0 0 i80486DX-25/33
1 i80486DX-50
2 i80486SX
3 i80486DX2
4 i80486SL
5 i80486SX2
7 i80486DX2WB
8 i80486DX4
9 i80486DX4WB
4 1 1 U5D(486DX)
2 U5S(486SX)
4 2 3 80486DX2WT
7 80486DX2WB
8 80486DX4
9 80486DX4WB
14 5x86
15 5x86WB
4 3 4 Cyrix Media GX
9 Cyrix 5x86
5 0 0 P5 A-step
1 P5
2 P54C
3 P24T OverDrive
4 P55C
5 DX4 OverDrive?
6 P5 OverDrive?
7 P54C
8 P55C(0.25)MMX
5 2 0 SSA5
1 5k86
2 5k86
3 5k86
6 K6
7 K6
8 K6-3D
9 K6PLUS-3D
5 3 0 Pentium Cx6X86 GXm
2 Std. Cx6x86
4 Cx6x86 GXm
5 4 - Nx586
5 5 - IDT C6 (WinChip)
6 0 0 PentiumPro A-step
1 Pentium Pro
3 Pentium II
4 P55CT (P54 overdrive)
5 Pentium II (0.25)
6 2 6 K6
7 K6
8 K6-3D
9 K6PLUS-3D
6 3 0 Cx6x86 MX/MII
很遗憾,没能找到最新的资料。哪位朋友有的,帮忙给我一份,谢谢。
———————————三、查看CPU所支持的功能/技术——————————
if (CPUID[4] and $800000)<>0 then
//支持MMX指令
else
//不支持
——————————————————————————————————
//CPU是否支持3DNow技术
function Is3DNowSupport: Boolean; assembler;
asm
push ebx
mov @Result, True
mov eax, $80000000 //查询扩展功能
dw $A20F
cmp eax, $80000000 //是否支持8000_0001h扩展功能
jbe @NOEXTENDED //不支持
mov eax, $80000001 //起动8000_0001h扩展功能
dw $A20F
test edx, $80000000 //测试第31位
jnz @EXIT //支持
@NOEXTENDED:
mov @Result, False
@EXIT:
pop ebx
end;
——————— 四、检测CPU实际运行频率 ——————————
//获取CPU实际运行频率,返回值以MHz为单位
function GetCPUSpeed: Double;
const
DelayTime = 500;
var
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
dw 310Fh // RDTSC指令
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := TimerLo / (1000.0 * DelayTime);
end;
————————————————以下为程序代码—————————————
———————————— 一、获取CPU厂家信息————————————
Const
CPUVendorIDs :array[0..5] of string = ('GenuineIntel','UMC UMC UMC','AuthenticAMD','CyrixInstead','NexGenDriven','CentaurHauls');
//将CPU厂家信息转换成字串形式
CPUVendors :array[0..5] of string = ('Intel','UMC','AMD','Cyrix','NexGen','CentaurHauls');
type TVendor = array [0..11] of char;
// 获取CPU厂家信息,返回值为TVendor类型
function GetCPUVendor : TVendor; assembler; register;
asm
PUSH EBX
PUSH EDI
MOV EDI,EAX
MOV EAX,0
DW $A20F //CPUID指令
MOV EAX,EBX
XCHG EBX,ECX
MOV ECX,4
@1:
STOSB
SHR EAX,8
LOOP @1
MOV EAX,EDX
MOV ECX,4
@2:
STOSB
SHR EAX,8
LOOP @2
MOV EAX,EBX
MOV ECX,4
@3:
STOSB
SHR EAX,8
LOOP @3
POP EDI
POP EBX
end;
调用方式:
var
Vendor: string;
VendorID, I: integer;
begin
Vendor := GetCPUVendor;
for i := 0 to High(CPUVendorIDs) do
begin
If Vendor = CPUVendorIDs[I] then
begin
Vendor := CPUVendors[I]; //把厂家信息精简一下,好看多了
VendorID := i;
break;
end;
end;
end;
———————————— 二、获取CPU类型信息 ————————————
const ID_BIT=$200000; //CPU ID 位标记
type TCPUID=array[1..4] of Longint;
//判断CPUID信息是否有效
function IsCPUIDAvailable : Boolean; register;
asm
PUSHFD //不允许直接存取,必须通过堆栈
POP EAX
MOV EDX,EAX
XOR EAX,ID_BIT
PUSH EAX
POPFD
PUSHFD
POP EAX
XOR EAX,EDX //检测ID位是否受影响
JZ @exit //CPUID无效
MOV AL,True //CPUID无效
@exit:
end;
//获取CPUID信息,返回值为TCPUID类型
function GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX
PUSH EDI
MOV EDI,EAX
MOV EAX,1
DW $A20F //CPUID指令
STOSD //CPUID[1]
MOV EAX,EBX
STOSD //CPUID[2]
MOV EAX,ECX
STOSD //CPUID[3]
MOV EAX,EDX
STOSD //CPUID[4]
POP EDI
POP EBX
end;
具体使用方法:
const
CPUSubModels: array[0..4] of string = ('Primary','OverDrive','Secondary','Reserved','Not Detected');
var
CPUID: TCPUID;
SubModel: string;
SubModelID, Family, Model, Stepping: Integer;
begin
//如果CPUID信息有效
if IsCPUIDAvailable then
begin
fillchar(CPUID, sizeof(CPUID), -1);
CPUID := GetCPUID;
SubModelID := CPUID[1] shr 12 and 3;
Family := CPUID[1] shr 8 and $F;
Model := CPUID[1] shr 4 and $F;
Stepping:= CPUID[1] and $F;
if SubModelID < 4 then
SubModel := CPUSubModels[SubModelID]
else
SubModel := CPUSubModels[4];
end;
end;
——————由所获取的信息,可在下表中找出相应的CPU类型————————
Family VendorID Model CPU类型
4 0 0 i80486DX-25/33
1 i80486DX-50
2 i80486SX
3 i80486DX2
4 i80486SL
5 i80486SX2
7 i80486DX2WB
8 i80486DX4
9 i80486DX4WB
4 1 1 U5D(486DX)
2 U5S(486SX)
4 2 3 80486DX2WT
7 80486DX2WB
8 80486DX4
9 80486DX4WB
14 5x86
15 5x86WB
4 3 4 Cyrix Media GX
9 Cyrix 5x86
5 0 0 P5 A-step
1 P5
2 P54C
3 P24T OverDrive
4 P55C
5 DX4 OverDrive?
6 P5 OverDrive?
7 P54C
8 P55C(0.25)MMX
5 2 0 SSA5
1 5k86
2 5k86
3 5k86
6 K6
7 K6
8 K6-3D
9 K6PLUS-3D
5 3 0 Pentium Cx6X86 GXm
2 Std. Cx6x86
4 Cx6x86 GXm
5 4 - Nx586
5 5 - IDT C6 (WinChip)
6 0 0 PentiumPro A-step
1 Pentium Pro
3 Pentium II
4 P55CT (P54 overdrive)
5 Pentium II (0.25)
6 2 6 K6
7 K6
8 K6-3D
9 K6PLUS-3D
6 3 0 Cx6x86 MX/MII
很遗憾,没能找到最新的资料。哪位朋友有的,帮忙给我一份,谢谢。
———————————三、查看CPU所支持的功能/技术——————————
if (CPUID[4] and $800000)<>0 then
//支持MMX指令
else
//不支持
——————————————————————————————————
//CPU是否支持3DNow技术
function Is3DNowSupport: Boolean; assembler;
asm
push ebx
mov @Result, True
mov eax, $80000000 //查询扩展功能
dw $A20F
cmp eax, $80000000 //是否支持8000_0001h扩展功能
jbe @NOEXTENDED //不支持
mov eax, $80000001 //起动8000_0001h扩展功能
dw $A20F
test edx, $80000000 //测试第31位
jnz @EXIT //支持
@NOEXTENDED:
mov @Result, False
@EXIT:
pop ebx
end;
——————— 四、检测CPU实际运行频率 ——————————
//获取CPU实际运行频率,返回值以MHz为单位
function GetCPUSpeed: Double;
const
DelayTime = 500;
var
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
dw 310Fh // RDTSC指令
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := TimerLo / (1000.0 * DelayTime);
end;