C++ 中的 CPUID 实现

发布于 2024-08-09 07:15:49 字数 344 浏览 14 评论 0原文

我想知道这里是否有人有一些可以从任何托管 .net 语言引用的 C++ CPUID 实现的好示例。

另外,如果情况并非如此,我是否应该注意 X86 和 X64 之间的某些实现差异?

我想使用 CPUID 来获取运行我的软件的机器上的信息(崩溃报告等...),并且我希望保持所有内容尽可能广泛兼容。

我问这个问题的主要原因是,尽管我有关于 CPU 寄存器等的基本知识,但在编写可能是所有机器指令的内容时,我完全是个菜鸟……

在人们开始告诉我 Google 之前:我在网上找到了一些例子,但通常它们并不意味着允许与托管代码进行交互,并且没有一个示例同时针对 X86 和 X64。大多数示例似乎都是 X86 特定的。

I would like to know if somebody around here has some good examples of a C++ CPUID implementation that can be referenced from any of the managed .net languages.

Also, should this not be the case, should I be aware of certain implementation differences between X86 and X64?

I would like to use CPUID to get info on the machine my software is running on (crashreporting etc...) and I want to keep everything as widely compatible as possible.

Primary reason I ask is because I am a total noob when it comes to writing what will probably be all machine instructions though I have basic knowledge about CPU registers and so on...

Before people start telling me to Google: I found some examples online, but usually they were not meant to allow interaction from managed code and none of the examples were aimed at both X86 and X64. Most examples appeared to be X86 specific.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

难理解 2024-08-16 07:15:49

访问原始 CPUID 信息实际上非常容易,这里有一个适用于 Windows、Linux 和 OSX 的 C++ 类:

#ifndef CPUID_H
#define CPUID_H

#ifdef _WIN32
#include <limits.h>
#include <intrin.h>
typedef unsigned __int32  uint32_t;

#else
#include <stdint.h>
#endif

class CPUID {
  uint32_t regs[4];

public:
  explicit CPUID(unsigned i) {
#ifdef _WIN32
    __cpuid((int *)regs, (int)i);

#else
    asm volatile
      ("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
       : "a" (i), "c" (0));
    // ECX is set to zero for CPUID function 4
#endif
  }

  const uint32_t &EAX() const {return regs[0];}
  const uint32_t &EBX() const {return regs[1];}
  const uint32_t &ECX() const {return regs[2];}
  const uint32_t &EDX() const {return regs[3];}
};

#endif // CPUID_H

要使用它,只需实例化该类的实例,加载您感兴趣的 CPUID 指令并检查寄存器。例如:

#include "CPUID.h"

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
  CPUID cpuID(0); // Get CPU vendor

  string vendor;
  vendor += string((const char *)&cpuID.EBX(), 4);
  vendor += string((const char *)&cpuID.EDX(), 4);
  vendor += string((const char *)&cpuID.ECX(), 4);

  cout << "CPU vendor = " << vendor << endl;

  return 0;
}

此维基百科页面告诉您如何使用 CPUID:http://en.wikipedia.org/wiki/CPUID

编辑:根据评论添加了适用于 Windows 的#include

Accessing raw CPUID information is actually very easy, here is a C++ class for that which works in Windows, Linux and OSX:

#ifndef CPUID_H
#define CPUID_H

#ifdef _WIN32
#include <limits.h>
#include <intrin.h>
typedef unsigned __int32  uint32_t;

#else
#include <stdint.h>
#endif

class CPUID {
  uint32_t regs[4];

public:
  explicit CPUID(unsigned i) {
#ifdef _WIN32
    __cpuid((int *)regs, (int)i);

#else
    asm volatile
      ("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
       : "a" (i), "c" (0));
    // ECX is set to zero for CPUID function 4
#endif
  }

  const uint32_t &EAX() const {return regs[0];}
  const uint32_t &EBX() const {return regs[1];}
  const uint32_t &ECX() const {return regs[2];}
  const uint32_t &EDX() const {return regs[3];}
};

#endif // CPUID_H

To use it just instantiate an instance of the class, load the CPUID instruction you are interested in and examine the registers. For example:

#include "CPUID.h"

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
  CPUID cpuID(0); // Get CPU vendor

  string vendor;
  vendor += string((const char *)&cpuID.EBX(), 4);
  vendor += string((const char *)&cpuID.EDX(), 4);
  vendor += string((const char *)&cpuID.ECX(), 4);

  cout << "CPU vendor = " << vendor << endl;

  return 0;
}

This Wikipedia page tells you how to use CPUID: http://en.wikipedia.org/wiki/CPUID

EDIT: Added #include <intrin.h> for Windows, per comments.

何以心动 2024-08-16 07:15:49

请参阅这篇关于 __cpuid 的 MSDN 文章

有一个使用 Visual Studio 2005 或更高版本进行编译的综合示例。对于 Visual Studio 6,您可以使用它代替编译器固有 __cpuid:

void __cpuid(int CPUInfo[4], int InfoType)
{
 __asm 
  {
     mov    esi, CPUInfo
     mov    eax, InfoType
     xor    ecx, ecx  
     cpuid  
     mov    dword ptr [esi +  0], eax
     mov    dword ptr [esi +  4], ebx  
     mov    dword ptr [esi +  8], ecx  
     mov    dword ptr [esi + 12], edx  
  }
}

对于 Visual Studio 2005,您可以使用它代替编译器固有 __cpuidex:

void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue)
{
 __asm 
  {
     mov    esi, CPUInfo
     mov    eax, InfoType
     mov    ecx, ECXValue
     cpuid  
     mov    dword ptr [esi +  0], eax
     mov    dword ptr [esi +  4], ebx  
     mov    dword ptr [esi +  8], ecx  
     mov    dword ptr [esi + 12], edx  
  }
}

See this MSDN article about __cpuid.

There is a comprehensive sample that compiles with Visual Studio 2005 or better. For Visual Studio 6, you can use this instead of the compiler instrinsic __cpuid:

void __cpuid(int CPUInfo[4], int InfoType)
{
 __asm 
  {
     mov    esi, CPUInfo
     mov    eax, InfoType
     xor    ecx, ecx  
     cpuid  
     mov    dword ptr [esi +  0], eax
     mov    dword ptr [esi +  4], ebx  
     mov    dword ptr [esi +  8], ecx  
     mov    dword ptr [esi + 12], edx  
  }
}

For Visual Studio 2005, you can use this instead of the compiler instrinsic __cpuidex:

void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue)
{
 __asm 
  {
     mov    esi, CPUInfo
     mov    eax, InfoType
     mov    ecx, ECXValue
     cpuid  
     mov    dword ptr [esi +  0], eax
     mov    dword ptr [esi +  4], ebx  
     mov    dword ptr [esi +  8], ecx  
     mov    dword ptr [esi + 12], edx  
  }
}
永言不败 2024-08-16 07:15:49

可能不完全是您正在寻找的,但英特尔有一个 用于枚举 Intel 64 位平台架构(处理器、缓存等)的好文章和示例代码,它似乎也涵盖了 32 位 x86 处理器。

Might not be exactly what you are looking for, but Intel have a good article and sample code for enumerating Intel 64 bit platform architectures (processor, cache, etc.) which also seems to cover 32 bit x86 processors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文