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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现