See what's going on with flipcode!

This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.


  CPU Detect
  Submitted by

I've had programmers block for a while now and I just had to write something. I remembered something about the assembler 'cpuid' instruction so I decided to test it out. I figured this sort of thing might be useful if I am writting an application that required a certain processor or I was just writting really optimized code. So I wrote this and compiled it as a static library. I also wrote an application that will spit out the features of your processor, thats availabe at my website.

Heres the first part of the code, the [.h] file. Each of the differant features detectable are defined. The cpuID function returns a pointer to the processor string (like the one in system under control panel for you Windows people, like the string GenuineIntel or AuthenticAMD) (Editor's note: see cpuid.h) And now the actual function definitions. Some of it is written in assembler, I optimized most of the code (instruction pairing, etc.) but I didn't look at it real closely. One more thing, you might notice that there isn't a function to tell the frequency of the processor. As far as I know (after reading the intel documents), 'cpuid' doesn't support this, well the Penium4 does. If you know how, I would love to hear it! Email me if you do-> (Editor's note: see cpuid.c) If you have any questions, email me. You can freely use this code, I don't care, but if you do, I'd at least like to hear from you! Hope this stuff is useful. -Andrew

Currently browsing [] (1,902 bytes) - [cpuID.h] - (3,085 bytes)

#ifndef _CPUID_H_
#define _CPUID_H_

/* When cpuid is called with a value of 0 in the EAX register, it returns a list of values in the EDX register. Each bit represents a feature (excluding reserved bits). If the bit is set, the feature exists. If it's cleared the feature isn't supported. */ #define CHECKFEATURE_ERROR 0x10000001 /* cpu feature check had a problem, call cpuFeatures */ #define CHECKFEATURE_X87FPU 0x00000001 /* cpu has x87 fpu */ #define CHECKFEATURE_VMODEE 0x00000002 /* cpu has Virtual 8086 mode enhancement */ #define CHECKFEATURE_DEBEXT 0x00000004 /* cpu has debugging extensions */ #define CHECKFEATURE_PGSEXT 0x00000008 /* cpu has page extensions */ #define CHECKFEATURE_TSCOUN 0x00000010 /* cpu has time stamp counter */ #define CHECKFEATURE_XXMSRS 0x00000020 /* cpu has RDMSR/WRMSR inst support */ #define CHECKFEATURE_PHAEXT 0x00000040 /* cpu has physical address extension */ #define CHECKFEATURE_MCHEXT 0x00000080 /* cpu has machine check exception */ #define CHECKFEATURE_CMPXCH 0x00000100 /* cpu has 8 byte cmp and xchg inst support */ #define CHECKFEATURE_APICON 0x00000200 /* cpu has APIC on chip */ #define CHECKFEATURE_SYSXXX 0x00000800 /* cpu has SYSENTER/SYSLEAVE */ #define CHECKFEATURE_MTRREG 0x00001000 /* cpu has memory type range registers */ #define CHECKFEATURE_PTEBIT 0x00002000 /* cpu has global PTE bit */ #define CHECKFEATURE_MCKARC 0x00004000 /* cpu has machine check architexture */ #define CHECKFEATURE_CMOVIN 0x00008000 /* cpu has CMOV inst support */ #define CHECKFEATURE_PGATTT 0x00010000 /* cpu has page attribute table */ #define CHECKFEATURE_PGSEX2 0x00020000 /* cpu has page size extension */ #define CHECKFEATURE_SERNUM 0x00040000 /* cpu has processor serial number */ #define CHECKFEATURE_CFLUSH 0x00080000 /* processor supports CFLUSH inst */ #define CHECKFEATURE_DBSTOR 0x00200000 /* cpu has debug store */ #define CHECKFEATURE_ACPICT 0x00400000 /* ACPI on processor */ #define CHECKFEATURE_MMXCMP 0x00800000 /* cpu has MMX technology */ #define CHECKFEATURE_FXXSTO 0x01000000 /* cpu supports FXSAVE/FXRSTORE inst */ #define CHECKFEATURE_SSEEXT 0x02000000 /* cpu has SSE extensions */ #define CHECKFEATURE_SSE2EX 0x04000000 /* cpu has sse2 extensions */ #define CHECKFEATURE_SSNOOP 0x08000000 /* cpu supports system snoop */ #define CHECKFEATURE_PTHERM 0x10000000 /* cpu has process thermomitor */

#ifdef _cplusplus extern "C" { #endif

/* When called, obtains a list of features the cpu supports */ extern unsigned int __cdecl cpuFeatures (void); /* Pass this one of the above defined features, -1 = error and if it returns the same value passed the feature exists if it returns 0 then the feature is un supported */ extern unsigned int __cdecl cpuCheckFeature (unsigned int feature); /* Returns a pointer to a string that the processor sends to the EBX, EDX, and ECX registers. e.g. GenuineIntel or AuthenticAMD. */ extern char* __cdecl cpuID (void);

#ifdef _cplusplus } #endif


Currently browsing [] (1,902 bytes) - [cpuID.c] - (1,291 bytes)

#include "cpuID.h"

unsigned int cpufeatures = 0; /* cpuFeatures will set this to the appropriate value to be used by cpuCheckFeature, DONT MODIFY */

unsigned int cpuFeatures (void) { unsigned int features; __asm { mov eax, 1 ;set request type to a feature list from processor cpuid ;send request lea ebx, features mov [ebx], edx ;save value }

cpufeatures = features; return features; }

unsigned int cpuCheckFeature (unsigned int feature) { if(!cpufeatures) /* cpuFeatures not called ? */ return 0x10000001;

if(cpufeatures&feature) /* feature exists, good- tell user */ return feature;

return 0; }

char* cpuID (void) { static char id[13];

__asm { lea ebx, id mov cl, 0

CLEARID: inc cl mov dword ptr [ebx], 0 cmp cl, 13 jb CLEARID }

__asm { xor eax, eax ;set request type to the string ID cpuid ;send request xchg eax, ebx ;swap so address register can be used lea ebx, id ;get destination string offset mov [ebx], eax ;save first four letters of string add ebx, 4 ;go up anther four bytes ;repeat for next two registers mov [ebx], edx add ebx, 4

mov [ebx], ecx }

return id; /* return pointer */ }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.


Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.