تطبيقات CPUID في C ++
سؤال
أود أن أعرف ما إذا كان لدى شخص ما هنا بعض الأمثلة الجيدة لتنفيذ CPUID C ++ الذي يمكن الرجوع إليه من أي لغات .NET المدارة.
أيضا، يجب أن يكون هذا هو الحال، هل يجب أن أدرك بعض الاختلافات في التنفيذ بين X86 و X64؟
أرغب في استخدام CPUID للحصول على معلومات حول الجهاز يعمل برامجي على (CrashReporting وما إلى ذلك ...) وأريد أن أبقي كل شيء متوافق على نطاق واسع قدر الإمكان.
السبب الأساسي الذي أسأله هو أنني مستجد تماما عندما يتعلق الأمر بكتابة ما سيكون من المحتمل أن يكون كل تعليمات آلية على الرغم من أن لدي معرفة أساسية حول سجلات وحدة المعالجة المركزية وهلم جرا ...
قبل أن يبدأ الأشخاص بإخباري عن Google: لقد وجدت بعض الأمثلة عبر الإنترنت، ولكن عادة ما لم يكن من المفترض أن تسمح بالتفاعل من التعليمات البرمجية المدارة ولم يهدف أي من الأمثلة إلى كل من X86 و X64. يبدو أن معظم الأمثلة محددة X86 الخاصة.
المحلول
الوصول إلى معلومات CPUID الخام هي في الواقع سهلة للغاية، وهنا فئة C ++ لذلك يعمل في Windows و Linux و 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
لاستخدامها فقط إنشاء مثيل للفئة، قم بتحميل تعليمات 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.
تعديل: وأضاف #include <intrin.h>
لنظام التشغيل Windows، لكل تعليقات.
نصائح أخرى
يرى هذه المادة MSDN حول __CPUID.
هناك عينة شاملة تتجمع مع Visual Studio 2005 أو أفضل. بالنسبة إلى Visual Studio 6، يمكنك استخدام هذا بدلا من برنامج التحويل البرمجي 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
}
}
بالنسبة إلى Visual Studio 2005، يمكنك استخدام هذا بدلا من التحويل البرمجي 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
}
}
قد لا يكون بالضبط ما تبحث عنه، ولكن إنتل لديها مقالة جيدة وعينة التعليمات البرمجية لتسجيل بنية Intel 64 بت منصة (المعالج، ذاكرة التخزين المؤقت، وما إلى ذلك) والتي يبدو أنها تغطي معالجات 32 بت X86.