一、获取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, TimerL 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;