1. Obtain CPU manufacturer information
Const
Cpuvendorids: array [0 .. 5] of string = ('genineintel ', 'umc UMC umc', 'authenticamd', 'cyrixinstead ', 'nexgendriven', 'centaurhauls ');
// Convert the CPU manufacturer information into a string
Cpuvendors: array [0 .. 5] of string = ('intel ', 'umc', 'amd', 'cyrix ', 'nexgen', 'centaurhauls ');
Type tvendor = array [0 .. 11] of char;
// Obtain the CPU manufacturer information. The returned value is of the tvendor type.
Function getcpuvendor: tvendor; receiver er; register;
ASM
Push EBX
Push EDI
MoV EDI, eax
MoV eax, 0
DW $ a20f // cpuid command
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;
Call method:
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]; // streamline the factory information.
Vendorid: = I;
Break;
End;
End;
End;
Ii. Obtain CPU type information
Const id_bit = $200000; // CPU ID
Type tcpuid = array [1 .. 4] of longint;
// determine whether the cpuid information is valid
function iscpuidavailable: Boolean; register;
ASM
pushfd // direct access is not allowed, stack
pop eax
mov edX, eax
XOR eax, id_bit
push eax
popfd
pushfd
pop eax
XOR eax, edX // check whether the ID bit is affected
JZ @ exit // invalid cpuid
mov Al, true // invalid cpuid
@ Exit:
end;
// obtain the cpuid information. The returned value is of the tcpuid type.
function getcpuid: tcpuid; assembler; register;
ASM
push EBX
push EDI
mov EDI, eax
mov eax, 1
DW $ a20f // cpuid command
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;
usage:
const
cpusubmodels: array [0 .. 4] of string = ('primary', 'overdrive ', 'secondary', 'reserved', 'not detected');
var
cpuid: tcpuid;
submodel: string;
submodelid, family, model, stepping: integer;
begin
// If the cpuid information is valid
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;
According to the obtained information, the corresponding CPU type can be found in the following table.
Family vendorid model cputype
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 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
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
K6PLUS-3D
6 3 0 cx6x86 MX/MII
Unfortunately, we cannot find the latest information. Which of the following is my friend? Could you give me a copy? Thank you.
Iii. View functions/technologies supported by CPU
If (cpuid [4] and $800000) <> 0 then
// Supports MMX commands
Else
// Not supported
// Whether the CPU supports the 3dnow Technology
Function is3dnowsupport: Boolean; aggreger;
ASM
Push EBX
MoV @ result, true
MoV eax, $80000000 // query Extension
DW $ a20f
CMP eax, $80000000 // whether the 8000_0001h Extension function is supported
Jbe @ noextended // not supported
MoV eax, $80000001 // start the 8000_0001h Extension function
DW $ a20f
Test edX, $80000000 // test 31st bits
Jnz @ exit // supported
@ Noextended:
MoV @ result, false
@ Exit:
Pop EBX
End;
Iv. Check the actual CPU running frequency
// Obtain the actual CPU running frequency. The return value is in the unit of 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 command
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;