#include <stdio.h>
#include <stdlib.h>


#define cpuid(mode, eax, ebx, ecx, edx) \
       __asm__("movl %4, %%eax\n\t" \
               "cpuid\n\t" \
               "movl %%eax, %0\n\t" \
               "movl %%ebx, %1\n\t" \
               "movl %%ecx, %2\n\t" \
               "movl %%edx, %3\n\t" \
               : : "m" (eax), "m" (ebx), "m" (ecx), "m" (edx), "im" (mode) : \
               "%eax", "%ebx" , "%ecx", "%edx", "memory" \
       )


main()
{
       char vendor_id[13], *yn[2] = {"no", "yes"};
       char *proctype[4] = {"Original OEM Processor",
                           "Intel Overdrive Processor",
                           "Dual Processor",
                           "Intel Reserved" };
       char *family[4] = {"Intel386", "Intel486", "Pentium", "P6"};
       int max_cpuid_val, tmp;
       int eax, ebx, ecx, edx;

       cpuid(0, max_cpuid_val, vendor_id[0], vendor_id[8], vendor_id[4]);

       printf("Maximum CPUID input value:              %d\n",
                       max_cpuid_val);
       vendor_id[12] = 0;
       printf("Vendor ID:                              %s\n",
                       vendor_id);

       if(max_cpuid_val == 0)
               exit(0);

       cpuid(1, eax, ebx, ecx, edx);

       printf("Stepping ID:                            %02X\n",
                       eax & 0xf);
       printf("Model:                                  %02X\n",
                       (eax & 0xf0) >> 4);
       tmp = (eax & 0xf00) >> 8;
       printf("Family:                                 %02X (%s)\n",
                       tmp, family[tmp - 3]);
       printf("Processor Type:                         %02X (%s)\n",
                       (eax & 0x3000) >> 12, proctype[(eax & 0x3000) >> 12]);

       printf("FPU - FPU on Chip:                      %s\n",
                       yn[edx & 0x00000001]);
       printf("VME - Virtual-8086 Mode Enhancements:   %s\n",
                       yn[(edx & 0x00000002) >> 1]);
       printf("DE - Debugging Extensions:              %s\n",
                       yn[(edx & 0x00000004) >> 2]);
       printf("PSE - Page Size Extensions:             %s\n",
                       yn[(edx & 0x00000008) >> 3]);
       printf("TSC - Time Stamp Counter:               %s\n",
                       yn[(edx & 0x00000010) >> 4]);
       printf("MSR - Model Specific Registers:         %s\n",
                       yn[(edx & 0x00000020) >> 5]);
       printf("PAE - Physical Address Extension:       %s\n",
                       yn[(edx & 0x00000040) >> 6]);
       printf("MCE - Machine Check Exception:          %s\n",
                       yn[(edx & 0x00000080) >> 7]);
       printf("CXS - CMPXCHG8B Instruction:            %s\n",
                       yn[(edx & 0x00000100) >> 8]);
       printf("APIC - APIC on Chip:                    %s\n",
                       yn[(edx & 0x00000200) >> 9]);
       printf("MTRR - Memory Type Range Registers:     %s\n",
                       yn[(edx & 0x00001000) >> 12]);
       printf("PGE - PTE Global Bit:                   %s\n",
                       yn[(edx & 0x00002000) >> 13]);
       printf("MCA - Machine Check Architecture:       %s\n",
                       yn[(edx & 0x00004000) >> 14]);
       printf("CMOV - Cond. Move/Cmp. Instructions:    %s\n",
                       yn[(edx & 0x00008000) >> 15]);
       printf("MMX - MMX Technology:                   %s\n",
                       yn[(edx & 0x00800000) >> 23]);

       printf("\n");
}