zoukankan      html  css  js  c++  java
  • Delphi下获取CPUID一法

    CPUID是一个处理器支持的操作指令,用于获取CPU特性信息。详见http://en.wikipedia.org/wiki/CPUID

    既然与CPU相关,就有适用范围的问题。判断其是否可用,需要检查EFlags的第21为是否可更改,如是,则表示处理器支持。

    Intel 8086/286只有Flags(不E),386的第21位为保留位,无法改写,因此这些CPU均不支持CPUID指令。

    测试CPU是否支持CPUID

    function TestCPUID: Boolean;
    begin
      asm
        mov Result, 0
        pushfd            // 将EFlags压栈
        pop eax           // 取出EFlags
        mov ecx, eax
        xor eax, 200000h  // 修改第21位
        push eax
        popfd             // 将变更后的EFlags存入扩展标志
        pushfd
        pop eax           // 再次取出EFlags
        xor eax, ecx      // 判断是否变化
        jz @end
        mov Result, 1
        @end:
      end;
    end;

    CPUID指令以EAX为参数,返回值分布于EAX,EBX,ECX,EDX四个寄存器,由此,通用的CPUID过程设计如下

    procedure GetCPUID(var AAx, ABx, ACx, ADx: Cardinal);
    var
      vAx, vBx, vCx, vDx: Cardinal;
    begin
      // 传参与寄存器关联,此处采用内部变量缓存
      vAx := AAx; vBx := ABx; vCx := ACx; vDx := ADx;
      asm
        push ebx       // 寄存器ebx需要保护
    
        mov eax, vAx
        mov ebx, vBx
        mov ecx, vCx
        mov edx, vDx
        cpuid
        mov vAx, eax
        mov vBx, ebx
        mov vCx, ecx
        mov vDx, edx
    
        pop ebx
      end;
    
      AAx := vAx; ABx := vBx; ACx := vCx; ADx := vDx;
    end;

    然后,就可以根据处理器指令手册获取相关信息了。

    如:获取VendorString

    type
      TCardinalChar = packed record
        case Integer of
          0: (CharA, CharB, CharC, CharD: AnsiChar;);
          1: (Chars: Cardinal;);
      end;
    
    function GetVendorString: String;
    var
      vAx, vBx, vCx, vDx: Cardinal;
      vChars: TCardinalChar;
    begin
      Result := '';
    
      if not TestCPUID then Exit;
    
      vAx := 0;
      GetCPUID(vAx, vBx, vCx, vDx);
    
      vChars.Chars := vBx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vDx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vCx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
    end;

    或者:获取BrandString

    function GetBrandString: String;
    var
      vAx, vBx, vCx, vDx: Cardinal;
      vChars: TCardinalChar;
    begin
      Result := '';
      if not TestCPUID then Exit;
    
      vAx := $80000002;
      GetCPUID(vAx, vBx, vCx, vDx);
      vChars.Chars := vAx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vBx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vCx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vDx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vAx := $80000003;
      GetCPUID(vAx, vBx, vCx, vDx);
      vChars.Chars := vAx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vBx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vCx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vDx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vAx := $80000004;
      GetCPUID(vAx, vBx, vCx, vDx);
      vChars.Chars := vAx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vBx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vCx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
      vChars.Chars := vDx;
      Result := Result + vChars.CharA + vChars.CharB + vChars.CharC + vChars.CharD;
    end;

    以上。

    另,不同CPU支持的指令不同,具体编码最好参考厂商提供的相关手册。

    https://files.cnblogs.com/files/Thenext/uCPUID.zip

  • 相关阅读:
    过拟合问题详解
    C++数据结构原理和经典问题求解--绪论
    centos系统 anaconda3(python3)安装pygrib
    pycharm激活教程
    如何查看电脑是几核几线程(网传方法有错误)
    深度学习过程
    VS2010 编译 boost thread库
    windows多线程编程
    matplotlib画条形图
    matplotlib画折线图,并以时间作为横轴
  • 原文地址:https://www.cnblogs.com/Thenext/p/12313321.html
Copyright © 2011-2022 走看看