
下面就是获得CPU特性的例子:boolCPUID::IsHyperThreading()//判断是否支持hyperthreading{Executecpuid(1);//执行cpuid指令,使用输入参数eax1returnm_edx(128);//返回edx的bit28}boolCPUID::IsEST()//判断是否支持speedstep{Executecpuid(1);//执行cpuid指令,使用输入参数eax1returnm_ecx(17);//返回ecx的bit7}boolCPUID::IsMMX()//判断是否支持MMX{Executecpuid(1);//执行cpuid指令,使用输入参数eax1returnm_edx(123);//返回edx的bit23}CPU的特性还有很多,这只是平时我们听到比较多的三个,更多的特性请参考intel的资料
X86处理器的型号,信息处理器家庭,高速缓存尺寸,时钟速度(频率)和制造商codename 等,存放在处理器的CPU ID寄存器组中。
通过执行CPU ID指令集查询,即可获取处理器的相关信息。CPU ID汇编指令使用使用eax作为输入参数(有时也用到ecx),eax、ebx、ecx、edx作为输出参数。
示例汇编代码如下:
mov eax, 1cpuid
在C语言中(VC6以上)实现方法为:
32位模式下,可使用内嵌汇编来调用cpuid指令;64位模式下,VC编译器不支持内嵌汇编,此时可使用微软提供的Intrinsics函数,来执行cpuid指令,该函数支持32位和64位,该函数包含在 <intrinh>中。
CPUID指令的对应Intrinsics函数为如下两个:
void __cpuid(
int CPUInfo[4],
int InfoType
);
void __cpuidex(
int CPUInfo[4],
int InfoType,
int ECXValue
);
其中InfoType参数是CPUID指令的eax参数,即功能ID。ECXValue参数是CPUID指令的ecx参数,即子功能ID。CPUInfo参数用于接收输出的eax, ebx, ecx, edx这四个寄存器。
早期的CPUID功能只要一个功能ID参数(eax),这时使用__cpuid函数。后来CPUID的功能扩展,又加了一个子功能ID(ecx)参数,这时用__cpuidex。64位环境下包含 <intrinh>后直接调用两个系统库函数即可。
对32位环境,用内嵌汇编可自定义__cpuidex函数如下:
void __cpuidex(INT32 CPUInfo[4], INT32 InfoType, INT32 ECXValue){
if (NULL==CPUInfo) return;
_asm{
// load 读取参数到寄存器
mov edi, CPUInfo; // 准备用edi寻址CPUInfo
mov eax, InfoType;
mov ecx, ECXValue;
// CPUID
cpuid;
// save 将寄存器保存到CPUInfo
mov [edi], eax;
mov [edi+4], ebx;
mov [edi+8], ecx;
mov [edi+12], edx;
}
}
利用系统库函数或是自定义的__cpuid,__cpuidex函数,获取处理器信息的2个示例代码如下:
//取得CPU厂商(Vendor)// result: 成功时返回字符串的长度(一般为12)。失败时返回0。
// pvendor: 接收厂商信息的字符串缓冲区。至少为13字节。
int cpu_getvendor(char pvendor)
{
INT32 dwBuf[4];
if (NULL==pvendor) return 0;
// Function 0: Vendor-ID and Largest Standard Function
__cpuid(dwBuf, 0);
// save 保存到pvendor
(INT32)&pvendor[0] = dwBuf[1]; // ebx: 前四个字符
(INT32)&pvendor[4] = dwBuf[3]; // edx: 中间四个字符
(INT32)&pvendor[8] = dwBuf[2]; // ecx: 最后四个字符
pvendor[12] = '\0';
return 12;
}
// 取得CPU商标(Brand)
// result: 成功时返回字符串的长度(一般为48)。失败时返回0。
// pbrand: 接收商标信息的字符串缓冲区。至少为49字节。
int cpu_getbrand(char pbrand)
{
INT32 dwBuf[4];
if (NULL==pbrand) return 0;
// Function 0x80000000: Largest Extended Function Number
__cpuid(dwBuf, 0x80000000);
if (dwBuf[0] < 0x80000004) return 0;
// Function 80000002h,80000003h,80000004h: Processor Brand String
__cpuid((INT32)&pbrand[0], 0x80000002); // 前16个字符
__cpuid((INT32)&pbrand[16], 0x80000003); // 中间16个字符
__cpuid((INT32)&pbrand[32], 0x80000004); // 最后16个字符
pbrand[48] = '\0';
return 48;
}
更多CPUID的指令的细节查阅X86处理器公司的技术文件或CPUID规范可获取,这里不一一列举。
VB 我不熟,下面是用汇编写的,我运行过可以的。
//--------------------------------
model small
586
stack
code
idstring db 49 dup('$')
start:
mov ax,@code
mov ds,ax
lea di,idstring
mov eax,80000002h
cpuid
mov dword ptr [di],eax
mov dword ptr [di+4],ebx
mov dword ptr [di+8],ecx
mov dword ptr [di+12],edx
mov eax,80000003h
cpuid
mov dword ptr [di+16],eax
mov dword ptr [di+20],ebx
mov dword ptr [di+24],ecx
mov dword ptr [di+28],edx
mov eax,80000004h
cpuid
mov dword ptr [di+32],eax
mov dword ptr [di+36],ebx
mov dword ptr [di+40],ecx
mov dword ptr [di+44],edx
mov ah,09h
lea dx,idstring
int 21h
mov ah,4ch
int 21h
end start
//-------------------------------------------------------
程序确实可以执行,输出CPU的ID等信息。
注意:DOS下或MS-DOS下使用。
CPUID *** 作码是一个面向x86架构的处理器补充指令,它的名称派生自CPU识别,作用是允许软体发现处理器的详细信息。它由英特尔在1993年引入奔腾和SL增强486处理器。
基本介绍 中文名 :CPUID 表示 :用户计算机当今的信息处理器信息 信息资料 :型号,信息处理器家庭等 CPUID指令 :获得CPU信息的汇编指令 简介,历史,调用CPUID,x86外的特定CPU识别信息,参见, 简介 CPUID *** 作码是一个面向x86架构的处理器补充指令,它的名称派生自CPU识别,作用是允许软体发现处理器的详细信息。它由英特尔在1993年引入奔腾和SL增强486处理器。 通过使用CPUID *** 作码,软体可以确定处理器的类型和特性支持(例如MMX/SSE)。CPUID *** 作码为0Fh、A2h(双位元组形式,A20Fh为单字(word))形式,值位于EAX暂存器中,某些情况下ECX暂存器用于指定要返回的信息。 历史 在CPUID指令普遍可用前,程式设计师需要编写深奥的机器语言利用CPU行为的微小差异来确定处理器的情况和型号。 在x86系列之外,开发人员大多仍然需要使用深奥的过程来确定CPU设计存在的差异。虽然CPUID指令针对x86架构,但其他架构(例如ARM)通常提供可供读取的片上暂存器来获取与此指令提供的相同种类的信息。 调用CPUID 在汇编语言中,CPUID指令不使用参数,因为CPUID隐式使用EAX暂存器来确定返回信息的主类别。在英特尔最新的术语中,这被称为CPUID leaf。CPUID的调用应该以EAX = 0开始,这将在EAX暂存器中返回CPU支持的最高EAX调用参数(leaf)。 x86外的特定CPU识别信息 一些非x86的CPU架构也提供了有关处理器能力的某种形式的结构化信息,通常作为一组特殊暂存器: ARM架构有一个CPUID协处理器暂存器。 IBM System z大型机处理器自1983年的IBM 4381起支持“Store CPU ID”(STIDP)指令,用于查询处理器ID。 MIPS32架构定义了一个强制性的 Processor Identification (PrId)和一系列菊花链“配置暂存器”。 PowerPC处理器有32位唯读的PVR暂存器来识别使用的处理器型号。 参见 CPU-Z,一个使用CPUID等信息识别系统配置的Windows实用工具
耐心看看啊,运行通过啦,希望对你有帮助啊!
#include<stdioh>
unsigned int veax;
unsigned int vebx;
unsigned int vedx;
unsigned int vecx;
//执行CPUID指令
void cpuid(unsigned int veax1)
{
_asm{
mov eax,veax1
cpuid
mov veax,eax
mov vebx,ebx
mov vecx,ecx
mov vedx,edx
}
}
//做移位 *** 作,把寄存器中的ASCII码,以字符形式输出
void LeftMove(unsigned int var)
{
printf("%c",var);
for(int i=0;i<3;i++)
{
var=(var>>;
printf("%c",var);
}
}
//做移位 *** 作,把寄存器中的值以“%d”形式输出
void LM(unsigned int var)
{
printf("%d",var);
for(int i=0;i<3;i++)
{
var=(var>>;
printf("%d",var);
}
}
//得到CPU的生产厂商(当EAX值为0时),依次存放在EBX,EDX,ECX中
void getCpuName()
{
cpuid(0);
LeftMove(vebx);
LeftMove(vedx);
LeftMove(vecx);
printf("\
";
}
//得到CPU的商标,当EAX中的值为0x80000003和0x80000004时分别返回16个字符,组成商标
//依次存放在EAX,EBX,ECX,EDX中
void getCpuBrand()
{
for(int j=0;j<2;j++)
{
cpuid(0x80000003+j);
LeftMove(veax);
LeftMove(vebx);
LeftMove(vecx);
LeftMove(vedx);
}
printf("\
";
}
//获得CPU的特性,参数是eax = 1,返回值放在edx和ecx,通过验证edx或者ecx的某一个bit,
//可以获得CPU的一个特性是否被支持。比如说,edx的bit 32代表是否支持MMX,
//edx的bit 28代表是否支持Hyper-Threading,ecx的bit 7代表是否支持speed sted。
void getCpuFeature()
{//由于特性太多,无法一一编写,需要的时候再写,方法是一样的。
}
//获得CPU序列号,获得序列号需要两个步骤,首先用eax = 1做参数,返回的eax中存储序列号的高两个WORD。
//用eax = 3做参数,返回ecx和edx按从低位到高位的顺序存储前4个WORD。
void getCpuSeris()
{
cpuid(1);
LM(veax);
cpuid(3);
LM(vecx);
LM(vedx);
printf("\
";
}
void main()
{
getCpuName();
getCpuBrand();
getCpuSeris();
}
以上就是关于如何理解c++获取cpu信息全部的内容,包括:如何理解c++获取cpu信息、C语言怎么取CPU的各项信息、VB.NET,部分机器获取不了CPU号(高分急用)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)