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

📄 cpuid.pas

📁 检测CPU信息和硬盘温度,以及硬盘使用时间和IP地址的小软件。
💻 PAS
字号:
unit cpuid;

interface
uses
  Windows;
const
  CPU_TYPE_INTEL     = 1;
  CPU_TYPE_AMD       = 2;

type
  TCpuInfo = Record
    //HasInstruction: Boolean;
    CPUType: Byte;
    DTS: Boolean;   //支持温度检测
    FID: Boolean;   //支持频率检测   AMD intel不知道去哪找
    VID: Boolean;   //支持电压检测   AMD
    Frequency: Double;
    multiplier: Double;
    Maxmultiplier: Double;
    FSB: Double;
    VendorIDString: array [0..11] of Char;  //厂家字串
    CpuName: array [0..47] of Char;         //CPU名称
    PhysicalCore: Byte;                     //物理核心数
  end;
var
  CpuInfo: TCpuInfo;
Function GetCpuInfo: TCpuInfo;
function GetCPUSpeed(var CpuSpeed: Double): Boolean;
implementation
const
  VendorIDIntel: array [0..11] of Char = 'GenuineIntel';
  VendorIDAMD: array [0..11] of Char = 'AuthenticAMD';

function HasCPUIDInstruction: Boolean;
const
  ID_FLAG = $200000;
asm
  PUSHFD
  POP     EAX
  MOV     ECX, EAX
  XOR     EAX, ID_FLAG
  AND     ECX, ID_FLAG
  PUSH    EAX
  POPFD
  PUSHFD
  POP     EAX
  AND     EAX, ID_FLAG
  XOR     EAX, ECX
  SETNZ   Result
end;

procedure CallCPUID(ValueEAX, ValueECX: Cardinal; var ReturnedEAX, ReturnedEBX, ReturnedECX, ReturnedEDX);
begin
  asm
    PUSH    EDI
    PUSH    EBX

    MOV     EAX, ValueEAX
    MOV     ECX, ValueECX
//    CPUID
    DB      0FH
    DB      0A2H
    MOV     EDI, ReturnedEAX
    MOV     Cardinal PTR [EDI], EAX
    MOV     EAX, ReturnedEBX
    MOV     EDI, ReturnedECX
    MOV     Cardinal PTR [EAX], EBX
    MOV     Cardinal PTR [EDI], ECX
    MOV     EAX, ReturnedEDX
    MOV     Cardinal PTR [EAX], EDX
    POP  EBX
    POP  EDI
  end;
end;

procedure ProcessIntel(var CPUInfo: TCpuInfo; HiVal: Cardinal);
var
  ExHiVal, EAX, EBX, ECX, EDX: Cardinal;
begin
  CPUInfo.CpuType := CPU_TYPE_INTEL;
  //CPUInfo.Manufacturer := 'Intel';
  //Todo :  FID, VID;
  if HiVal >= 4 then
  begin
    CallCPUID(4, 0, EAX, EBX, ECX, EDX);
    CPUInfo.PhysicalCore := ((EAX and $FC000000) shr 26) + 1;  //核心数
  end;
  if Hival >=6 then
  begin
    CallCPUID(6, 0, EAX, EBX, ECX, EDX);
    CPUInfo.DTS := (EAX and 1) = 1;      //温度
    //CPUInfo.FID := (ECX and 1) = 1;      //IA32_MPERF MSR and IA32_APERF MSR
  end;
  //取CPU名称
  CallCPUID($80000000, 0, ExHiVal, EBX, ECX, EDX);
  if ExHiVal >= $80000002 then
    CallCPUID($80000002, 0, CPUInfo.CpuName[0], CPUInfo.CpuName[4], CPUInfo.CpuName[8], CPUInfo.CpuName[12]);
  if ExHiVal >= $80000003 then
    CallCPUID($80000003, 0, CPUInfo.CpuName[16], CPUInfo.CpuName[20], CPUInfo.CpuName[24], CPUInfo.CpuName[28]);
  if ExHiVal >= $80000004 then
    CallCPUID($80000004, 0, CPUInfo.CpuName[32], CPUInfo.CpuName[36], CPUInfo.CpuName[40], CPUInfo.CpuName[44]);
end;


procedure ProcessAMD(var CPUInfo: TCpuInfo; HiVal: Cardinal);
var
  ExHiVal, EAX, EBX, ECX, EDX: Cardinal;
begin
  CPUInfo.CpuType := CPU_TYPE_AMD;
  //CPUInfo.Manufacturer := 'AMD';
  //取CPU名称
  CallCPUID($80000000, 0, ExHiVal, EBX, ECX, EDX);
  if ExHiVal >= $80000002 then
    CallCPUID($80000002, 0, CPUInfo.CpuName[0], CPUInfo.CpuName[4], CPUInfo.CpuName[8], CPUInfo.CpuName[12]);
  if ExHiVal >= $80000003 then
    CallCPUID($80000003, 0, CPUInfo.CpuName[16], CPUInfo.CpuName[20], CPUInfo.CpuName[24], CPUInfo.CpuName[28]);
  if ExHiVal >= $80000004 then
    CallCPUID($80000004, 0, CPUInfo.CpuName[32], CPUInfo.CpuName[36], CPUInfo.CpuName[40], CPUInfo.CpuName[44]);
  if ExHival >= $80000008 then    //get PhysicalCore;
  begin
    CallCPUID($80000008,0, EAX, EBX, ECX, EDX);
    CpuInfo.PhysicalCore := ECX and $F + 1;    //核心数
  end;
  if ExHiVal >= $80000007 then
  begin
    CallCPUID($80000007,0, EAX, EBX, ECX, EDX);
    CpuInfo.DTS := (EDX and 1) = 1;   //温度
    CpuInfo.FID := (EDX and 2) = 2;   //频率
    CpuInfo.VID := (EDX and 4) = 4;   //电压
  end;
end;

Function GetCpuInfo: TCpuInfo;
var
  Hival: Cardinal;
begin
  FillChar(Result, sizeof(Result), 0);
  Result.PhysicalCore := 1;
  CallCPUID(0, 0, HiVal, Result.VendorIDString[0], Result.VendorIDString[8], Result.VendorIDString[4]);
  if Result.VendorIDString = VendorIDIntel then
    ProcessIntel(Result, HiVal)
  else if Result.VendorIDString = VendorIDAMD then
    ProcessAMD(Result, HiVal);
end;

function ReadTimeStampCounter: Int64; assembler;
asm
        DW      $310F
end;

function GetCPUSpeed(var CpuSpeed: Double): Boolean;
var
  T0, T1: Int64;
  CountFreq: Int64;
  Cycles: Int64;
  Stamp0, Stamp1: Int64;
  Ticks: Double;
  Priority: Integer;
  Thread: THandle;
begin
  CpuSpeed := 0.0;
  Stamp0 := 0;
  stamp1 := 0;

  Thread := GetCurrentThread();
  Result := QueryPerformanceFrequency(CountFreq);
  if not Result  then Exit;

  QueryPerformanceCounter(T0);
  T1 := T0;
  Priority := GetThreadPriority(Thread);
  if Priority <> THREAD_PRIORITY_ERROR_RETURN then SetThreadPriority(Thread, THREAD_PRIORITY_TIME_CRITICAL);
  try
    while T1 - T0 < 50 do
    begin
      QueryPerformanceCounter(T1);
      Stamp0 := ReadTimeStampCounter;
    end;
    T0 := T1;

    while T1 - T0 < 1000 do
    begin
      QueryPerformanceCounter(T1);
      Stamp1 := ReadTimeStampCounter;
    end;
  finally
    if Priority <> THREAD_PRIORITY_ERROR_RETURN then SetThreadPriority(Thread, Priority);
  end;

  Cycles := Stamp1 - Stamp0;
  Ticks := (T1 - T0) / CountFreq * 100000;
  CpuSpeed := Cycles / Ticks;
end;



end.

⌨️ 快捷键说明

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