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-> Assembler015@hotmail.com (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 [cpu.zip] (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

    #endif

Currently browsing [cpu.zip] (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.