最近突然有需求獲取CPUID。Google後看到些東西,整理出來,防止忘記。因爲我慣用Delphi,這裏只列出Delphi下用法。 緩存
CPUID是一個處理器支持的操做指令,用於獲取CPU特性信息。詳見http://en.wikipedia.org/wiki/CPUID。 測試
既然與CPU相關,就有適用範圍的問題。判斷其是否可用,須要檢查EFlags的第21爲是否可更改,如是,則表示處理器支持。 ui
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 code
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 ip
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支持的指令不一樣,具體編碼最好參考廠商提供的相關手冊。
get