回 帖 发 新 帖 刷新版面

主题:全面获取CPU信息

■ 全面获取CPU信息

————————————————以下为程序代码—————————————

———————————— 一、获取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, TimerLo: 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;

回复列表 (共3个回复)

沙发

好像挺有用的。
但就是有点看不懂。

板凳

学习学习!楼主辛苦了!

3 楼


收藏了,楼主辛苦了,支持一下。[em2]

我来回复

您尚未登录,请登录后再回复。点此登录或注册