Delphi编程 -- 使用CPUID指令获取CPU信息

unit CPU;

interface

uses Types;

const

  //Version Information bitmask
  BITMASK_ExtendedFamilyID=$0FF00000;
  BITMASK_ExtendedModelID= $000F0000;
  BITMASK_ProcessorType=   $00003000;
  BITMASK_FamilyID=        $00000F00;
  BITMASK_ModelID=         $000000F0;
  BITMASK_SteppingID=      $0000000F;

  //Processor Type
  ProcessorType_OriginalOEMProcessor=    $00000000;
  ProcessorType_IntelOverDriveProcessor= $00001000;
  ProcessorType_DualProcessor=           $00002000;
  ProcessorType_IntelReserved=           $00003000;

type

  //register used in cpuid instruction
  TCPUIDRegister=packed record
    EAX:DWORD;
    case Integer of
    0://register
    (
      EBX:DWORD;
      ECX:DWORD;
      EDX:DWORD;
    );
    1://version information string
    (
      VIS1:array[1..4] of Char;
      VIS2:array[1..4] of Char;
      VIS3:array[1..4] of Char;
    );
  end;

  PCPUIDRegister=^TCPUIDRegister;

  //basic cupid information
  TCPUIDBasicInformation=packed record
    //EAX=0
    HighestBasicProcessorInformationValue:Cardinal;
    VendorIdentificationString:string[12];
    //EAX=1
    ExtendedFamileyID,
    ExtendedModelID,
    ProcessorType,
    FamilyID,
    ModelID,
    SteppingID:DWORD;
  end;

  PCPUIDBasicInformation=^TCPUIDBasicInformation;

  TCPUInfo=class
  private
    fSupportForCPUID:Boolean;
  private
    function CPUID(Value:DWORD):TCPUIDRegister;
    function Get_CPUIDBasicInformation:TCPUIDBasicInformation;
  public
    constructor Create;
  public
    property SupportForCPUID:Boolean read fSupportForCPUID;
    property CPUIDBasicInformation:TCPUIDBasicInformation read Get_CPUIDBasicInformation;
  end;

implementation

uses Dialogs,SysUtils;

{ TCPUInfo }

function TCPUInfo.CPUID(Value:DWORD): TCPUIDRegister;
var
  VEAX,VEBX,VECX,VEDX:DWORD;
begin
  asm
    pushad
    mov eax,Value
    cpuid
    mov VEAX,eax
    mov VEBX,ebx
    mov VECX,ecx
    mov VEDX,edx
    popad
  end;
  with Result do
  begin
    EAX:=VEAX;
    EBX:=VEBX;
    ECX:=VECX;
    EDX:=VEDX;
  end;
end;

constructor TCPUInfo.Create;
const
  EF_ID:DWORD=$200000;
var
  EFID:DWORD;
begin
  fSupportForCPUID:=False;
  asm
    //save current register
    pushad
    //move old eflags to ebx
    pushfd
    pop eax
    //move old eflags to ebx
    mov ebx,eax
    //revert EF_ID
    xor eax,EF_ID
    push eax
    popfd
    //move new eflags to eax
    pushfd
    pop eax
    //test EF_ID
    xor eax,ebx
    mov EFID,eax
    //restore register
    popad
  end;
  if (EFID xor EF_ID)=0 then fSupportForCPUID:=True;
end;

function TCPUInfo.Get_CPUIDBasicInformation: TCPUIDBasicInformation;
var
  CPUIDRegister:TCPUIDRegister;
begin
  CPUIDRegister:=CPUID(0);
  with CPUIDRegister,Result do
  begin
    HighestBasicProcessorInformationValue:=EAX;
    VendorIdentificationString:=VIS1+VIS3+VIS2;
  end;
  CPUIDRegister:=CPUID(1);
  with CPUIDRegister,Result do
  begin
    ExtendedFamileyID:=EAX and BITMASK_ExtendedFamilyID;
    ExtendedModelID:=EAX and BITMASK_ExtendedModelID;
    ProcessorType:=EAX and BITMASK_ProcessorType;
    FamilyID:=EAX and BITMASK_FamilyID;
    ModelID:=EAX and BITMASK_ModelID;
    SteppingID:=EAX and BITMASK_SteppingID;
  end;
end;

end.

posted @ 2008-05-24 01:00  Max Woods  阅读(1966)  评论(0编辑  收藏  举报