⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.pas

📁 理论考试程序,可以自由下载,学习,请多多指点,批评
💻 PAS
📖 第 1 页 / 共 3 页
字号:
//This unit can be used to detect the cpu model.
unit cpu;
interface
uses Windows, Mmsystem, Sysutils, Math, Dialogs;
type 
    TCpuRec=record
       Name:string[128]; 
       Vendor:string[12]; 
       Frequency:word; 
       Family:integer; 
       Model:integer; 
       Stepping:integer; 
       L1DCache:word; 
       L1ICache:word; 
       L2Cache:word; 
     end; 
    TCpuType = (cpu8086, cpu286, cpu386, cpu486, cpuPentium); 
    TCpuData=object 
      function GetCPUIDSupport:Boolean; 
      function GetVendorString:string; 
      function GetCPUFrequency:word; 
      procedure GetFMS(var Family,Model,Stepping:byte); 
      function GetMaxCpuId:dword; 
      function CheckFPU:Boolean; 
      function CheckTSC:Boolean;
      function CheckMSR:Boolean; 
      function CheckMPS:Boolean; 
      function GetNoCpus:cardinal; 
      function CheckPN:Boolean; 
      function CheckCMPXCHG8B:Boolean; 
      function CheckCMOVe:Boolean; 
      function CheckSelfSnoop:Boolean; 
      function CheckDebugTraceStore:Boolean; 
      function CheckFXSAVEFXRSTOR:Boolean; 
      function CheckMMX:Boolean; 
      function CheckMMXplus:Boolean; 
      function CheckSSE:Boolean; 
      function CheckSSE2:Boolean; 
      function CheckAMD3DNow:Boolean; 
      function CheckAMD3DNowPlus:Boolean; 
      function GetMaxExtendedFunctions:dword; 
      procedure GetExtendedFMS(var Family,Model,Stepping:byte); 
      function GetExtendedCpuName:string; 
      function GetExtendedL1DCache:word; 
      function GetExtendedL1ICache:word; 
      function GetExtendedL2Cache:word; 

      function CheckCeleron:Boolean; 
      function CheckPentiumIII:Boolean; 
      function CheckXeon:Boolean; 
      function CheckPentium4:Boolean; 
      function CheckIthanium:Boolean; 
      function IntelP5N:string; 
      function IntelP6N:string; 
      function AMDK5N:string; 
      function Cyrix686N:string; 
      function GenericCpuN:string; 
      function P5CacheL1DI:word; 
      function P6CacheL1DI:word; 
      function P6CacheL2:word; 

      function AuthenticAMD:TCpuRec; 

      function GenuineIntel:TCpuRec; 
      function CyrixInstead:TCpuRec; 
      function GenericCPU:TCpuRec; 
     end; 
const 
Intel486:array[0..8] of string= 
('Intel 486 DX', 
  'Intel 486 DX', 
  'Intel 486 SX', 
  'Intel 486 DX2', 
  'Intel 486 SL', 
  'Intel 486 SX2', 
  'Intel 486 DX2', 
  'Intel 486 DX4', 
  'Intel 486 DX4'); 
UMC486:array[0..1] of string= 
('UMC U5D', 
  'UMC U5S'); 
AMD486:array[0..5] of string= 
('AMD 486 DX2', 
  'AMD 486 DX2', 
  'AMD 486 DX4', 
  'AMD 486 DX4', 
  'AMD 5x86', 
  'AMD 5x86'); 
IntelP5:array[0..6] of string= 
('Intel Pentium P5 A-Step', 
  'Intel Pentium P5', 
  'Intel Pentium P54C', 
  'Intel Pentium P24T Overdrive', 
  'Intel Pentium MMX P55C', 
  'Intel Pentium P54C', 
  'Intel Pentium MMX P55C'); 
  NexGenNx586='NexGen Nx586'; 
  Cyrix4x86='VIA Cyrix 4x86'; 
  Cyrix5x86='VIA Cyrix 5x86'; 
  CyrixMediaGX='VIA Cyrix Media GX'; 
  CyrixM1='VIA Cyrix 6x86'; 
  CyrixM2='VIA Cyrix 6x86MX'; 
  CyrixIII='VIA Cyrix III'; 
  AMDK5:array[0..3] of string= 
  ('AMD SSA5 (PR75/PR90/PR100)', 
   'AMD 5k86 (PR120/PR133)', 
   'AMD 5k86 (PR166)', 
   'AMD 5k86 (PR200)'); 
  AMDK6:array[0..4] of string= 
  ('AMD K6 (166~233)', 
   'AMD K6 (266~300)', 
   'AMD K6-2', 
   'AMD K6-III', 
   'AMD K6-2+ or K6-III+'); 
   Centaur:array[0..2] of string= 
   ('Centaur C6', 
    'Centaur C2', 
    'Centaur C3'); 
   Rise:array[0..1] of string= 
   ('Rise mP6', 
    'Rise mP6'); 
   IntelP6:array[0..7] of string= 
   ('Intel Pentium Pro A-Step', 
    'Intel Pentium Pro', 
    'Intel Pentium II', 
    'Intel Pentium II', 
    'Intel Pentium II', 
    'Intel Pentium III', 
    'Intel Pentium III', 
    'Intel Pentium III'); 
   AMDK7:array[0..3] of string= 
    ('AMD Athlon(tm) Processor', 
     'AMD Athlon(tm) Processor', 
     'AMD Duron(tm) Processor', 
     'AMD Thunderbird Processor'); 
   IntelP4='Intel Pentium 4'; 
var CpuData:TCpuData; 
implementation 
function TCpuData.GetCPUIDSupport:Boolean; 
var TempDetect:dword; 
begin 
asm 
  pushf 
  pushfd 
  push eax 
  push ebx 
  push ecx 
  push edx 

  pushfd 
  pop eax 
  mov ebx,eax 
  xor eax,$00200000 
  push eax 
  popfd 
  pushfd 
  pop eax 
  push ebx 
  popfd 
  xor eax,ebx 
  mov TempDetect,eax 

  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
  popfd 
  popf 
end; 
GetCPUIDSupport:=(TempDetect=$00200000); 
end; 
function TCpuData.GetVendorString:string; 
var s1,s2,s3:array[0..3] of char; 
    TempVendor:string; 
    i:integer; 
begin 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,0 
  db $0F,$A2               /// cpuid 
  mov s1,ebx 
  mov s2,edx 
  mov s3,ecx 
  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
end; 
TempVendor:=''; 
for i:=0 to 3 do 
  TempVendor:=TempVendor+s1[i]; 
for i:=0 to 3 do 
  TempVendor:=TempVendor+s2[i]; 
for i:=0 to 3 do 
  TempVendor:=TempVendor+s3[i]; 
GetVendorString:=TempVendor; 
end; 
function TCpuData.GetCPUFrequency:word; 
const 
  timePeriod= 1000; 
var 
  HighFreq,TestFreq,Count1,Count2:int64; 
  TimeStart:integer; 
  TimeStop:integer; 
  ElapsedTime:dword; 
  StartTicks:dword; 
  EndTicks:dword; 
  TotalTicks:dword; 
begin 
  StartTicks:=0; 
  EndTicks:=0; 
  if QueryPerformanceFrequency(HighFreq) then begin 

    TestFreq:=HighFreq div 100; 

    QueryPerformanceCounter(Count1); 
    repeat 
      QueryPerformanceCounter(Count2); 
    until Count1<>Count2; 

    asm 
      push ebx 
      xor eax,eax 
      xor ebx,ebx 
      xor ecx,ecx 
      xor edx,edx 
      db $0F,$A2               /// cpuid 
      db $0F,$31               /// rdtsc 
      mov StartTicks,eax 
      pop ebx 
    end; 

    repeat 
      QueryPerformanceCounter(Count1); 
    until Count1-Count2>=TestFreq; 

    asm 
      push ebx 
      xor eax,eax 
      xor ebx,ebx 
      xor ecx,ecx 
      xor edx,edx 
      db $0F,$A2               /// cpuid 
      db $0F,$31               /// rdtsc 
      mov EndTicks,eax 
      pop ebx 
    end; 

    ElapsedTime:=MulDiv(Count1-Count2,1000000,HighFreq); 
  end 
  else begin 
    timeBeginPeriod(1); 
    TimeStart:=timeGetTime; 

    repeat 
      TimeStop:=timeGetTime; 
    until TimeStop <> TimeStart; 

    asm 
      push ebx 
      xor eax,eax 
      xor ebx,ebx 
      xor ecx,ecx 
      xor edx,edx 
      db $0F,$A2               /// cpuid 
      db $0F,$31               /// rdtsc 
      mov StartTicks,eax 
      pop ebx 
    end; 

    repeat 
      TimeStart:=timeGetTime; 
    until TimeStart-TimeStop>=timePeriod; 

    asm 
      push ebx 
      xor eax,eax 
      xor ebx,ebx 
      xor ecx,ecx 
      xor edx,edx 
      db $0F,$A2               /// cpuid 
      db $0F,$31               /// rdtsc 
      mov EndTicks,eax 
      pop ebx 
    end; 
    timeEndPeriod(1); 

    ElapsedTime:=(TimeStart-TimeStop)*1000; 
  end; 
  TotalTicks:=EndTicks-StartTicks; 
  result:=TotalTicks div ElapsedTime; 
end; 
procedure TCpuData.GetFMS(var Family,Model,Stepping:byte); 
var TempFlags:dword; 
    BinFlags:array[0..31] of byte; 
    i,pos:integer; 
begin 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,1 
  db $0F,$A2               /// cpuid 
  mov TempFlags,eax 
  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
end; 
for i:=0 to 31 do 
  begin 
   BinFlags[i]:=TempFlags mod 2; 
   TempFlags:=TempFlags div 2; 
  end; 
family:=0; 
model:=0; 
stepping:=0; 
  pos:=0; 
  for i:=0 to 3 do 
   begin 
    stepping:=stepping+(BinFlags[pos]*StrToInt(FloatToStr(Power(2,i)))); 
    inc(pos); 
   end; 
  pos:=4; 
  for i:=0 to 3 do 
   begin 
    model:=model+(BinFlags[pos]*StrToInt(FloatToStr(Power(2,i)))); 
    inc(pos); 
   end; 
  pos:=8; 
  for i:=0 to 3 do 
   begin 
    family:=family+(BinFlags[pos]*StrToInt(FloatToStr(Power(2,i)))); 
    inc(pos); 
   end; 
end; 
function TCpuData.GetMaxCpuId:dword; 
var TempMax:dword; 
begin 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,0 
  db $0F,$A2               /// cpuid 
  mov TempMax,eax 
  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
end; 
GetMaxCpuId:=TempMax; 
end; 
function TCpuData.CheckFPU:Boolean; 
label NoFpu; 
var TempCheck:dword; 
begin 
TempCheck:=1; 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,1 
  db $0F,$A2               /// cpuid 
  test edx,$1 
  jz NoFpu 
  mov edx,0 
  mov TempCheck,edx 
NoFpu: 
  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
  end; 
CheckFpu:=(TempCheck=0); 
end; 
function TCpuData.CheckTSC:Boolean; 
label NoTSC; 
var TempCheck:dword; 
begin 
TempCheck:=1; 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,1 
  db $0F,$A2               /// cpuid 
  test edx,$10 
  jz NoTSC 
  mov edx,0 
  mov TempCheck,edx 
NoTSC: 
  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
  end; 
CheckTSC:=(TempCheck=0); 
end; 
function TCpuData.CheckMSR:Boolean; 
label NoMSR; 
var TempCheck:dword; 
begin 
TempCheck:=1; 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,1 
  db $0F,$A2               /// cpuid 
  test edx,$20 
  jz NoMSR 
  mov edx,0 
  mov TempCheck,edx 
NoMSR: 
  pop edx 
  pop ecx 
  pop ebx 
  pop eax 
  end; 
CheckMSR:=(TempCheck=0); 
end; 
function TCpuData.CheckMPS:Boolean; 
var SysInfo:TSystemInfo; 
begin 
GetSysTemInfo(SysInfo); 
CheckMPS:=(SysInfo.dwNumberOfProcessors>1); 
end; 
function TCpuData.GetNoCpus:cardinal; 
var SysInfo:TSystemInfo; 
begin 
GetSystemInfo(SysInfo); 
GetNoCpus:=SysInfo.dwNumberOfProcessors; 
end; 
function TCpuData.CheckPN:Boolean; 
label NoPN; 
var TempCheck:dword; 
begin 
TempCheck:=1; 
asm 
  push eax 
  push ebx 
  push ecx 
  push edx 
  mov eax,1 
  db $0F,$A2               /// cpuid 
  test edx,$40000 
  jz NoPN 
  mov edx,0 
  mov TempCheck,edx 
NoPN: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -