1.24. STRUCTURES
#include <stdio.h>
#ifdef GNUC
static inline void cpuid(int code, int a, int b, int c, int d) {
asm volatile("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(code));
}
#endif
#ifdef _MSC_VER
#include <intrin.h>
#endif
struct CPUID_1_EAX
{
unsigned int stepping:4;
unsigned int model:4;
unsigned int family_id:4;
unsigned int processor_type:2;
unsigned int reserved1:2;
unsigned int extended_model_id:4;
unsigned int extended_family_id:8;
unsigned int reserved2:4;
};
int main()
{
struct CPUID_1_EAX *tmp;
int b[4];
#ifdef _MSC_VER
__cpuid(b,1);
#endif
#ifdef GNUC
cpuid (1, &b[0], &b[1], &b[2], &b[3]);
#endif
tmp=(struct CPUID_1_EAX *)&b[0];
printf ("stepping=%d\n", tmp->stepping);
printf ("model=%d\n", tmp->model);
printf ("family_id=%d\n", tmp->family_id);
printf ("processor_type=%d\n", tmp->processor_type);
printf ("extended_model_id=%d\n", tmp->extended_model_id);
printf ("extended_family_id=%d\n", tmp->extended_family_id);
return 0;
};
AfterCPUIDfillsEAX/EBX/ECX/EDX, these registers are to be written in theb[]array. Then, we have a
pointer to theCPUID_1_EAXstructure and we point it to the value inEAXfrom theb[]array.
In other words, we treat a 32-bitintvalue as a structure. Then we read specific bits from the structure.
MSVC
Let’s compile it in MSVC 2008 with/Oxoption:
Listing 1.350: Optimizing MSVC 2008
_b$ = -16 ; size = 16
_main PROC
sub esp, 16
push ebx
xor ecx, ecx
mov eax, 1
cpuid