Получение CPUID
#include < stdio.h> #define REG_EAX reg[0] #define REG_EBX reg[1] #define REG_ECX reg[3] #define REG_EDX reg[2] void cpuid(void); void check_flag(int); int reg[5]; char *vendor; int main(int argc, char *argv[]) { reg[5] = 0; //Если выполнить cpuid с EAX=0, то: //EAX - максимальное значение, с которым можно выполнять cpuid //EBX:EDX:ECX - строка - 12-байтный идентификатор производителя REG_EAX = 0; cpuid(); vendor = (char *) R_EBX; printf("Vendor: %s\n", vendor); //Если в EAX=1, то cpuid установит регистры в соответствии с //с возможностями процессора. REG_EAX = 1; cpuid(); //В EAX находится информация о типе ,модели, семействе // и модификации процессора printf("Family: %i\n", (REG_EAX & 0xF00) >> 8); //EAX bits 11-8 printf("Model: %i\n", (REG_EAX & 0xF0) >> 4); //EAX bits 7-4 printf("Stepping: %i\n", REG_EAX & 0xF); //EAX bits 3-0 printf("Type: "); switch ( (REG_EAX & 0x3000) >> 12 ) { case 0: printf("OEM\n"); break; case 1: printf("Overdrive\n"); break; case 2: printf("Dual\n"); break; } //Проверяем установлены ли определенные биты в регистре EDX //от них зависит, присутствуют ли некоторые возможности //процессора printf(" FPU : "); check_flag(0); printf(" VMode Extensions : "); check_flag(1); printf(" Debugging Extensions : "); check_flag(2); printf(" 4-Megabyte Pages : "); check_flag(3); printf(" RDTSC Instruction : "); check_flag(4); printf(" Machine-Specific Registers : "); check_flag(5); printf(" Extended Physical Addressing : "); check_flag(6); printf(" Machine-Check Exception : "); check_flag(7); printf(" CMPXCHG8B Instruction : "); check_flag(8); printf(" APIC : "); check_flag(9); printf(" SYSENTER, SYSEXIT Instructions : "); check_flag(10); printf(" Memory Type Range Registers (MTRR): "); check_flag(12); printf(" Global Pages : "); check_flag(13); printf(" Machine Check Architecture : "); check_flag(14); printf(" CMOVcc, FCMOV Instructions : "); check_flag(15); printf(" Page Attributes Table : "); check_flag(16); printf(" MMX : "); check_flag(23); printf(" FXSAVE, FXRSTOR Instructions : "); check_flag(24); printf(" SSE : "); check_flag(25); printf(" SSE2 : "); check_flag(26); } //Функция проверяет установлен ли бит номер flag в REG_EDX void check_flag(int flag) { int mask=1; mask <<= flag; if ( (REG_EDX & mask) != 0) { printf("found\n"); } else { printf("NOT FOUND\n"); } } //Функция выполняет инструкцию CPUID, и сохраняет после нее //регистры в REG_EAX, REG_EBX, REG_ECX и REG_EDX void cpuid() { asm("cpuid": "=a"(REG_EAX), "=b"(REG_EBX), "=c"(REG_ECX), "=d"(REG_EDX): "a"(REG_EAX)); }
Оставить комментарий
Комментарии
1.
31 октября 2006, 17:04:33
it isnot true .this code is for C
2.
27 октября 2006, 19:58:01
#define REG_EAX reg[0]
#define REG_EBX reg[1]
#define REG_ECX reg[3]
#define REG_EDX reg[2]
ITS TRUE?
#define REG_ECX reg[3]
#define REG_EDX reg[2]
#define REG_EBX reg[1]
#define REG_ECX reg[3]
#define REG_EDX reg[2]
ITS TRUE?
#define REG_ECX reg[3]
#define REG_EDX reg[2]
3.
27 октября 2006, 18:15:58
oo.its very great work thanks
4.
5 марта 2005, 08:46:44
Данную программу пришлось немного переделать под Visual C++ (вызов #define CPUID _asm _emit 0x0f _asm _emit 0xa2), также были небольшие проблемы с выводом производителя . В целом программа составлена неплохо.
5.
9 ноября 2004, 15:02:07
Не работает из-за asm (так это пишут в Linux, компилятор GCC). Про ассемблер под C\C++ Borland для ДОСА надо смотреть в его документации.
6.
+0 / -1
4 августа 2004, 15:28:10
НИ ФИГА НЕ РАБОТАЕТ ПРОГА
Я ИСПОЛЬЗОВАЛ С\С++ BORLAND ДЛЯ ДОСА
Я ИСПОЛЬЗОВАЛ С\С++ BORLAND ДЛЯ ДОСА