问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

C语言怎么取CPU的各项信息?

发布网友 发布时间:2022-04-20 05:45

我来回答

2个回答

热心网友 时间:2023-08-07 00:52

  X86处理器的型号,信息处理器家庭,高速缓存尺寸,时钟速度(频率)和制造商codename 等,存放在处理器的CPU ID寄存器组中。

  通过执行CPU ID指令集查询,即可获取处理器的相关信息。CPU ID汇编指令使用使用eax作为输入参数(有时也用到ecx),eax、ebx、ecx、edx作为输出参数。

示例汇编代码如下:

mov    eax, 1
cpuid

  在C语言中(VC6以上)实现方法为:

  32位模式下,可使用内嵌汇编来调用cpuid指令;64位模式下,VC编译器不支持内嵌汇编,此时可使用微软提供的Intrinsics函数,来执行cpuid指令,该函数支持32位和64位,该函数包含在 <intrin.h>中。
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位环境下包含 <intrin.h>后直接调用两个系统库函数即可。

对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规范可获取,这里不一一列举。

热心网友 时间:2023-08-07 00:52

intel IA32架构下CPU提供了获取CPU信息的指令CPUID,用该指令能获取CPU信息,使用方法和说明如下。要注意的是,一下如有小于号的,都不是英文的小于号,要用都得该为英文的小于号。 1、什么是cpuid指令 CPUID指令是intel IA32架构下获得CPU信息的汇编指令,可以得到CPU类型,型号,制造商信息,商标信息,序列号,缓存等一系列CPU相关的东西。 2、cpuid指令的使用 cpuid使用eax作为输入参数,eax,ebx,ecx,edx作为输出参数,举个例子: __asm { mov eax, 1 cpuid ... } 以上代码以1为输入参数,执行cpuid后,所有寄存器的值都被返回值填充。针对不同的输入参数eax的值,输出参数的意义都不相同。 为了更好的在C++中使用cpuid指令,可以使用类对指令进行封装,在类中定义一个专门的函数负责cpuid的执行,他需要一个输入参数。还需要定义四个成员变量存储cpuid执行以后返回来的值。由于这四个寄存器都是32位长的,可以使用unsinged long 类型变量存储。 typedef unsigned long DWORD class CPUID { public: ... private: void Executecpuid(DWORD eax); // 用来实现cpuid DWORD m_eax; // 存储返回的eax DWORD m_ebx; // 存储返回的ebx DWORD m_ecx; // 存储返回的ecx DWORD m_edx; // 存储返回的edx ... } void CPUID::Executecpuid(DWORD veax) { // 因为嵌入式的汇编代码不能识别 类成员变量 // 所以定义四个临时变量作为过渡 DWORD deax; DWORD debx; DWORD decx; DWORD dedx; __asm { mov eax, veax ;将输入参数移入eax cpuid ;执行cpuid mov deax, eax ;以下四行代码把寄存器中的变量存入临时变量 mov debx, ebx mov decx, ecx mov dedx, edx } m_eax = deax; // 把临时变量中的内容放入类成员变量 m_ebx = debx; m_ecx = decx; m_edx = dedx; } 这样就可以通过直接调用Executecupid()函数的方式来执行cpuid指令了,返回值存在类成员变量m_eax, m_ebx, m_ecx和m_edx中。 3、获得CPU的制造商信息(Vender ID String) 把eax = 0作为输入参数,可以得到CPU的制造商信息。 cpuid指令执行以后,会返回一个12字符的制造商信息,前四个字符的ASC码按低位到高位放在ebx,中间四个放在edx,最后四个字符放在ecx。比如说,对于intel的cpu,会返回一个“GenuineIntel”的字符串,返回值的存储格式为: 31 23 15 07 00 EBX| u (75)| n (6E)| e (65)| G (47) EDX| I (49)| e (65)| n (6E)| i (69) ECX| l (6C)| e (65)| t (74)| n (6E) 因此可以这样实现他: string CPUID::GetVID() { char cVID[13]; // 字符串,用来存储制造商信息 memset(cVID, 0, 13); // 把数组清0 Executecpuid(0); // 执行cpuid指令,使用输入参数 eax = 0 memcpy(cVID, &m_ebx, 4); // 复制前四个字符到数组 memcpy(cVID+4, &m_edx, 4); // 复制中间四个字符到数组 memcpy(cVID+8, &m_ecx, 4); // 复制最后四个字符到数组 return string(cVID); // 以string的形式返回 } 4、获得CPU商标信息(Brand String) 在我的电脑上点击右键,选择属性,可以在窗口的下面看到一条CPU的信息,这就是CPU的商标字符串。CPU的商标字符串也是通过cpuid得到的。由于商标的字符串很长(48个字符),所以不能在一次cpuid指令执行时全部得到,所以intel把它分成了3个操作,eax的输入参数分别是0x80000002,0x80000003,0x80000004,每次返回的16个字符,按照从低位到高位的顺序依次放在eax, ebx, ecx, edx。因此,可以用循环的方式,每次执行完以后保存结果,然后执行下一次cpuid。 string CPUID::GetBrand() { const DWORD BRANDID = 0x80000002; // 从0x80000002开始,到0x80000004结束 char cBrand[49]; // 用来存储商标字符串,48个字符 memset(cBrand, 0, 49); // 初始化为0 for (DWORD i = 0; i<3; i++) // 依次执行3个指令 { Executecpuid(BRANDID + i); memcpy(cBrand + i*16, &m_eax, 16); // 每次执行结束后,保存四个寄存器里的asc码到数组 } // 由于在内存中,m_eax, m_ebx, m_ecx, m_edx是连续排列 // 所以可以直接以内存copy的方式进行保存 return string(cBrand); // 以string的形式返回 } 5、检测CPU特(CPU feature) 现在的intel CPU,台式机的好点的都支持Hyper-Threading了,移动的要支持Speed Sted。这些都是CPU的特性。CPU的特性可以通过cpuid获得,参数是eax = 1,返回值放在edx和ecx,通过验证edx或者ecx的某一个bit,可以获得CPU的一个特性是否被支持。比如说,edx的bit 32代表是否支持MMX,edx的bit 28代表是否支持Hyper-Threading,ecx的bit 7代表是否支持speed sted。下面就是获得CPU特性的例子: bool CPUID::IsHyperThreading() // 判断是否支持hyper-threading { Executecpuid(1); // 执行cpuid指令,使用输入参数 eax = 1 return m_edx & (1<<28); // 返回edx的bit 28 } bool CPUID::IsEST() // 判断是否支持speed step { Executecpuid(1); // 执行cpuid指令,使用输入参数 eax = 1 return m_ecx & (1<<7); // 返回ecx的bit 7 } bool CPUID::IsMMX() // 判断是否支持MMX { Executecpuid(1); // 执行cpuid指令,使用输入参数 eax = 1 return m_edx & (1<<23); // 返回edx的bit 23 } CPU的特性还有很多,这只是平时我们听到比较多的三个,更多的特性请参考intel的资料。
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
我要买狗!!!高手来!!!人在天津 93年,骗子一人设局卖掉河北1座大桥,被捕后大笑:他们真去拆了 看了很多狗,不知道为什么我就是喜欢京巴,真的超可爱,找了很多地方都没... 植物大战僵尸魔幻版怎么安 怎么下载植物大战僵尸魔幻最新版 植物大战僵尸魔幻版中文版下载 植物大战僵尸魔幻版中文在哪下载 以闪亮之名体验服官方正版如何下载 以闪亮之名 以闪亮之名内测版什么时候上线? 两个三角形放在一起,重叠部分的面积占小三角形3分之一,占大三角形的... 迷你厨房小鸡蛋哪来的? 迷你方便面和超级袖珍的方便面哪个更受人喜爱? 迷你小厨房是什么时候发明的? 迷你厨房做的食品能吃吗? 小火锅的简单做法,小火锅怎么做最正宗 迷你小厨房怎么设计? 儿童迷你厨房玩具套装 过家家做饭真煮食玩农家院快... 迷你小厨房可以做饭要拼多长时间 怎么用喝完奶的箱子做一个迷你小厨房? 如何把迷你小厨房改造得更大更实用? 一元迷你小厨房哪里买 抖音迷你厨房怎么拍的 计算机C语言中的“C”代表什么意思? 迷你厨房怎么做? 迷你厨房成为网络爆款,为何它能成为时下最流行的... 如果手的肤色很黑,该挑选什么颜色的指甲油呢? 手比较黑,什么颜色指甲油能显白又干净的效果 女人的手比较黑,想做个美甲,应该选择什么颜色呢? 手黑适合什么颜色的手表? 手黑的人适合用什么颜色的指甲油 C语言 编程实现获取cpu信息 如何通过命令行获取计算机CPU 详细信息? 怎样用C语言获取硬件信息 Linux c 语言怎么方便的读取 cpu,磁盘信息 用C语言怎么得到电脑的CPU序列号,硬盘序列号等信息 objective-c 怎么获取cpu信息 请教下:C语言获取计算机系统CPU使用率,内存使用... C语言(VC++6.0)获取cpu编码 如何用C语言获取硬盘或主板或CPU的序列号 如何用c语言程序获取计算机信息 C语言怎么获取硬件信息【网卡序号。。。】 在c语言中如何取得cpuid linux下用c语言实现查cpu类型和型号等信息 C语言读取计算机CPU的序列号、硬盘(网卡、机器名) 请问怎么用c语言获取电脑(windows)的cpu,内存,... C语言获取CPU tick 陌陌发送信息受限制,怎样解封? 陌陌发出去是黄箭头怎样解决 跪求电影《狼》,【在线观看】免费百度云资源 跪求狼的电影有哪些排名榜,【在线观看】免费百度...
  • 焦点

最新推荐

猜你喜欢

热门推荐