The MASM Forum

General => The Laboratory => Topic started by: Mark44 on February 22, 2014, 04:08:06 AM

Title: My version of a CPU identification utility
Post by: Mark44 on February 22, 2014, 04:08:06 AM
I've noticed several posts with code on how to identify which CPU you're running. I've recently been learning about the various SSE technologies as well as AVX, and I needed to be able to tell which of these technologies was supported on my Intel i7 processor. I've attached my own take on a CPU ID utility.

Here's an example of the info that it provides.
C:\Users\Mark\Documents\Visual Studio 2010\Projects\CPUInfo\Debug>cpuinfo
Extended + family ID: 06
Extended + model ID: 3a
Stepping: 9
Microarchiture: Ivy Bridge

CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU has SSE2.
CPU has SSE3.
CPU has SSE 4.1.
CPU has SSE 4.2.
CPU has AVX.
CPU does not have AVX2.


One feature of my code that I haven't seen elsewhere is that it displays the (Intel-specific) microarchitecture, which is useful to know if you're reading the Intel documentation. A shortcoming is that the code I wrote was a quick-and-dirty utility that works on the one machine I tested it on.
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 22, 2014, 04:26:54 AM
Mark,

good approach. You would have presumably more answers if you would write an additional version with an external assembler. Apart from that it's a solid work.

Gunther
Title: Re: My version of a CPU identification utility
Post by: TWell on February 22, 2014, 04:43:16 AM
Binary compiled with msvc2010 sp1 using msvcrt.dll
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 22, 2014, 04:45:53 AM
Jochen, Hutch, and I, and many others have written various versions of CPU ID routines
search the old forum

Title: Re: My version of a CPU identification utility
Post by: dedndave on February 22, 2014, 04:51:31 AM
i am running XP SP3
for the EXE that Timppa compiled...

(http://imageshack.com/a/img845/7417/h2sr.png)

never saw that one before - lol
Title: Re: My version of a CPU identification utility
Post by: GoneFishing on February 22, 2014, 04:54:11 AM
Here's the output for my CPU:
Quote
Extended + family ID: 06
Extended + model ID: 17
Stepping: a
Microarchiture: Enhanced Intel Core Microarchitecture

CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU has SSE2.
CPU has SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.
Compiles and runs nicely here  :t
Title: Re: My version of a CPU identification utility
Post by: GoneFishing on February 22, 2014, 04:56:07 AM
Quote from: dedndave on February 22, 2014, 04:51:31 AM
i am running XP SP3
for the EXE that Timppa compiled...

(http://imageshack.com/a/img845/7417/h2sr.png)

never saw that one before - lol
Probably you don't have right version of msvcrt.dll
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 22, 2014, 04:58:07 AM
you think ?
Title: Re: My version of a CPU identification utility
Post by: GoneFishing on February 22, 2014, 04:58:40 AM
shure
check the imports
[EDIT]: Hmm ... strange ,  maybe it's Win XP's kernel32.dll that throws an error ?
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 22, 2014, 04:59:04 AM
Dave,

Quote from: dedndave on February 22, 2014, 04:51:31 AM
i am running XP SP3
for the EXE that Timppa compiled...

(http://imageshack.com/a/img845/7417/h2sr.png)

never saw that one before - lol

that's very strange.

Mark,

works fine under Windows XP (emulation) and native Windows 7 (64 bit). Here is the output:

Extended + family ID: 06
Extended + model ID: 3a
Stepping: 9
Microarchiture: Ivy Bridge

CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU has SSE2.
CPU has SSE3.
CPU has SSE 4.1.
CPU has SSE 4.2.
CPU has AVX.
CPU does not have AVX2.

F:\MatMul>


Gunther
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 22, 2014, 05:14:49 AM
Quote from: Gunther on February 22, 2014, 04:26:54 AM
Mark,

good approach. You would have presumably more answers if you would write an additional version with an external assembler. Apart from that it's a solid work.

Gunther
At the moment, all I have is the MS assembler in VS 10. I will look into downloading one of the other assemblers I've seen described here.
Title: Re: My version of a CPU identification utility
Post by: jj2007 on February 22, 2014, 05:28:45 AM
Quote from: dedndave on February 22, 2014, 04:51:31 AM
i am running XP SP3
for the EXE that Timppa compiled...

Same problem here, XP SP3 & can't find the entry point :(
Title: Re: My version of a CPU identification utility
Post by: TWell on February 22, 2014, 05:32:05 AM
My bad, now corrected. :icon_redface:

Quote from: dedndave on February 22, 2014, 04:51:31 AM
i am running XP SP3
for the EXE that Timppa compiled...

(http://imageshack.com/a/img845/7417/h2sr.png)

never saw that one before - lol
I forgot to link msvcrt_winxp.obj from WDDK when using msvcrt.lib/msvcrt.dll
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 22, 2014, 05:41:00 AM
Hi Mark,

Quote from: Mark44 on February 22, 2014, 05:14:49 AM
At the moment, all I have is the MS assembler in VS 10. I will look into downloading one of the other assemblers I've seen described here.

that's a good idea. In the upper right corner of the forum you'll find MASM32 download link. A nearly 100% MASM compatible assembler is jWasm (http://www.japheth.de/JWasm.html), which I would strongly recommend. It's fast, lean and well maintained by our forum member Japheth. Moreover, some MASM bugs are eliminated. Another similar tool is the Solar Assembler (http://www.oby.ro/sol_asm/), which is written and maintained by forum member and Global Moderator BogdanOntanu.

In the other direction you have the NASM like tools like NASM (http://www.nasm.us/) and YASM (http://yasm.tortall.net/Download.html), both not bad and worth a try. Another alternative is FASM (http://flatassembler.net/download.php).

I've installed in parallel MASM, jWasm, YASM and GAS for Windows XP, Windows 7, Linux and BSD. That's not a problem. Have fun and happy installing.

Gunther
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 22, 2014, 06:30:09 AM
Gunther,
I'll check those out. jWasm and Solar sound interesting, from what I've read about them on this forum.

Back about 20 years ago I was a co-author of a book on targeting DOS using assembly, and did a lot of work with Borland's Turbo Assembler (TASM). I did all of the compiling/assembling and linking from the command line. At the moment I'm doing everything through VS, and the switches for MASM (via VS) are something of a mystery to me, although I'm coming along.
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 22, 2014, 06:31:39 AM
that one works, Timppa   :t

results for prescott w/htt...
Extended + family ID: 0f
Extended + model ID: 04
Stepping: 3
Unknown microarchitecture
CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU has SSE2.
CPU has SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.

not sure about the "microarchitecture" value - but the rest appears to be correct
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 22, 2014, 10:49:05 AM
Mark,

Quote from: Mark44 on February 22, 2014, 06:30:09 AM
Back about 20 years ago I was a co-author of a book on targeting DOS using assembly, and did a lot of work with Borland's Turbo Assembler (TASM). I did all of the compiling/assembling and linking from the command line. At the moment I'm doing everything through VS, and the switches for MASM (via VS) are something of a mystery to me, although I'm coming along.
there are a few old TASM fans floating around here (including me). But unfortunately, it's no longer maintained.

A real assembly language coder should be capable to do the necessary steps via the command line. I'm sure you can do it, too.
jwasm -h brings for example:

JWasm v2.08a, Sep  7 2012, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

   JWasm [options] asm-file [options] [asm-file] ... [@env_var]

options:
-<0|1|..|10>[p]      Set CPU: 0=8086 (default), 1=80186, 2=80286, 3=80386,
                     4=80486, 5=Pentium, 6=PPro, 7=P2, 8=P3, 9=P4, 10=x86-64.
                     <p> allows privileged instructions.
-c                   Assemble without linking (always set)
-C<p|u|x>            Set OPTION CASEMAP: p=NONE, u=ALL,
                     x=NOTPUBLIC (default).
-D<name>[=text]      Define text macro
-e<number>           Set error limit number (default=50)
-EP                  Output preprocessed listing to stdout
-eq                  don't display error messages
-Fd[=<file_name>]    Write import definition file
-Fi<file_name>       Force <file_name> to be included
-Fl[=<file_name>]    Write listing file
-Fo<file_name>       Set object file name
-Fw<file_name>       Set errors file name
-FPi                 80x87 instructions with emulation fixups
-FPi87               80x87 instructions (default)
-fpc                 Disallow floating-point instructions (.NO87)
-fp<n>               Set FPU, <n> is: 0=8087 (default), 2=80287, 3=80387
-G<c|d|z>            Use Pascal, C or Stdcall calling convention
-I<directory>        Add directory to list of include directories
-m<t|s|c|m|l|h|f>    Set memory model:
                     (Tiny, Small, Compact, Medium, Large, Huge, Flat)
-nc=<name>           Set class name of code segment
-n<d|m|t>=<name>     Set name of data segment, module or text segment
-q, -nologo          Don't display version and copyright information
-Sa                  Maximize source listing
-safeseh             Assert all exception handlers are declared
-Sf                  Generate first pass listing
-Sg                  Display generated code in listing
-Sn                  Suppress symbol-table listing
-Sx                  List false conditionals
-w                   Same as /W0 /WX
-W<number>           Set warning level number (default=2, max=4)
-WX                  Treat all warnings as errors
-X                   Ignore INCLUDE environment path
-zcm                 C names are decorated with '_' prefix (default)
-zcw                 No name decoration for C symbols
-Zd                  Add line number debug info (OMF & COFF only)
-Zf                  Make all symbols public
-zf<0|1>             Set FASTCALL type: 0=MS VC style (default),
                     1=OW register calling convention
-Zg                  Generated code is to exactly match Masm's one
-Zi                  Add symbolic debug info (OMF & COFF only)
-zlc                 No OMF records about data in code
-zld                 No OMF records about far call optimization
-zlf                 No COFF .file entry in symbol table
-zls                 No COFF auxiliary entries for sections in symbol table
-Zm                  Masm v5.1 compatibility
-Zne                 Disable syntax extensions not supported by Masm
-Zp[n]               Set structure alignment, n=<1|2|4|8|16|32>
-Zs                  Perform syntax check only
-zt<0|1|2>           Set STDCALL symbol decoration: 0=No name decoration,
                     1=No '@size' suffix for functions, 2=Full (default)
-Zv8                 Enable Masm v8+ PROC visibility
-zze                 No name decoration for exported symbols
-zzs                 Store decorated name of start address (COFF only)
@env_var             Environment variable or file containing further commands
output formats:
-bin                 plain binary file
-coff                32-bit COFF format object file
-elf                 32-bit ELF format object file
-elf64               64-bit ELF format object file
-mz                  DOS MZ binary file
-omf                 OMF format object file (default)
-win64               64-bit COFF format object file

and yasm -h brings:

usage: yasm [option]* file
Options:
    --version               show version text
    --license               show license text
    -h, --help              show help text
    --arch=<arch>           select architecture (list with -a help)
     -a <arch>
    --parser=<parser>       select parser (list with -p help)
     -p <parser>
    --preproc=<preproc>     select preprocessor (list with -r help)
     -r <preproc>
    --oformat=<format>      select object format (list with -f help)
     -f <format>
    --dformat=<debug>       select debugging format (list with -g help)
     -g <debug>
    --lformat=<list>        select list format (list with -L help)
     -L <list>
    --list=<listfile>       name of list-file output
     -l <listfile>
    --objfile=<filename>    name of object-file output
     -o <filename>
    --mapfile=<filename>    name of map-file output
    --machine=<machine>     select machine (list with -m help)
     -m <machine>
    --force-strict          treat all sized operands as if `strict' was used
    -w                      inhibits warning messages
    -W                      enables/disables warning
    -M                      generate Makefile dependencies on stdout
    -E <file>               redirect error messages to file
    -s                      redirect error messages to stdout
    -e, --preproc-only      preprocess only (writes output to stdout by default)

    -i <path>               add include path
    -I <path>               add include path
    -P <filename>           pre-include file
    -d <macro[=value]>      pre-define a macro, optionally to value
    -D <macro[=value]>      pre-define a macro, optionally to value
    -u <macro>              undefine a macro
    -U <macro>              undefine a macro
    -X <style>              select error/warning message style (`gnu' or `vc')
    --prefix=<prefix>       prepend argument to name of all external symbols
    --suffix=<suffix>       append argument to name of all external symbols
    --postfix=<suffix>      append argument to name of all external symbols

Files are asm sources to be assembled.

Sample invocation:
   yasm -f elf -o object.o source.asm

Report bugs to bug-yasm@tortall.net

It's easy to handle, just like in the good old DOS days.

Gunther
Title: Re: My version of a CPU identification utility
Post by: TWell on February 22, 2014, 08:29:50 PM
This version compiled with gcc.
asm part stripped to different file.
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 22, 2014, 10:15:03 PM
Hi TWell,

your new version works like a charme. Interesting enough, you've done the external assembler part with GAS.  :t Is that your favorite tool? It performs not bad and one has the the feeling like in the good old days.

Gunther
Title: Re: My version of a CPU identification utility
Post by: TWell on February 22, 2014, 11:06:41 PM
Quote from: Gunther on February 22, 2014, 10:15:03 PM
Hi TWell,

your new version works like a charme. Interesting enough, you've done the external assembler part with GAS.  :t Is that your favorite tool? It performs not bad and one has the the feeling like in the good old days.

Gunther
(g)as is not my favorite at all.
I just made masm code first and then convert that object file for as.exe with ObjConv.exe and edit that file.
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 23, 2014, 12:02:21 AM
TWell,

Quote from: TWell on February 22, 2014, 11:06:41 PM
(g)as is not my favorite at all.
I just made masm code first and then convert that object file for as.exe with ObjConv.exe and edit that file.

okay. But you can link the masm code directly. Why that indirection?

Gunther
Title: Re: My version of a CPU identification utility
Post by: TWell on February 23, 2014, 12:33:16 AM
Quote from: Gunther on February 23, 2014, 12:02:21 AM
But you can link the masm code directly. Why that indirection?

Gunther
making that program just with gcc/as only.

EDIT: compiled with gcc 2.95.3 too
Title: Re: My version of a CPU identification utility
Post by: FORTRANS on February 23, 2014, 12:46:47 AM
Hi,

   I ran the program on an older machine, and the first version
did not run; "not a valid Win32 application"  The gcc version works.
Here is the output.

G:\WORK\CPUID>cpuinfo1
Extended + family ID: 06
Extended + model ID: 08
Stepping: 3
Microarchiture: Unknown

CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU does not have SSE2.
CPU does not have SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.


   I can run it on some other old computers if wanted.

Steve N.
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 23, 2014, 04:07:52 AM
dedndave and FORTRANS,
To identify the microarchitecture I used the information listed in the Intel Optimization Reference Manual (July 2013), in appendix C (section 3.1). I added a comment in my code listing my source for this info. The table I drew from lists only recent Intel microarchitectures - Haswell, Ivy Bridge, Sandy Bridge, Westmere, Nehalem, Enhanced Intel Core, Intel Core. All of these have family IDs of 06h, so the family ID of your (dedndave's) machine is not listed. The family ID of FORTRANS's machine is 06h, but your model ID of 08h isn't listed in the table I drew from.

I have an older version of the Intel optimization docs from 2007 that contains information about the processors that were current at that time. For a family ID of 0Fh and model ID of 3, 4, or 6 (dedndave's machine), the microarchitecture is NetBurst. The machine that FORTRANS is using isn't listed in that older table. FORTRANS's machine is obviously pretty old, as it supports only MMX and nothing newer. If someone has saved a copy of the Intel Optimization reference that is older than Nov 2007, it might be listed there.

I'm happy to see there was so much interest in the code I wrote! I will update my microarchitecture identification logic and repost the revised version within a couple of days.
Mark 
Title: Re: My version of a CPU identification utility
Post by: MichaelW on February 23, 2014, 04:15:17 AM
Mark,

I compiled your source from the first post in this thread with the VC++ Toolkit 2003 compiler, no problems, but a warning with /W3:

CPUInfo.c(153) : warning C4244: '=' : conversion from 'long' to 'short', possible loss of data

Running the exe on my P3 I get:

Extended + family ID: 06
Extended + model ID: 07
Stepping: 3
Microarchiture: Unknown

CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU does not have SSE2.
CPU does not have SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.


All correct AFAIK, but when I run it on my 3.06GHz P4 Northwood (the first P4 with HT) I get:

Extended + family ID: 0f
Extended + model ID: 02
Stepping: 9
Unknown microarchitecture
CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU has SSE2.
CPU has SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.


AFAIK the SSE3 is not correct, and as a test, since I don't have any MASM version that can assemble SSE3 instructions set up, I assembled and linked this source with as/ld (no as warnings or errors):

.intel_syntax noprefix
.section .text
    lddqu xmm0, X
    ret
.section .data
.balign 16
X:
.octa 0


And running the exe on both systems I get exception number c000001eh, which per ntstatus.h is STATUS_INVALID_LOCK_SEQUENCE. But I suspect that this is not conclusive proof, because I seem to recall something about the OS needing to enable instruction set extensions.
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 23, 2014, 06:47:28 AM
Mark,
some time back, i wrote a test program that you may find useful

in the process of writing the code, i corrected some errors that were in the Intel manuals
i also added the AMD processors (at that time) to create a single BMP file

http://dedndave.x10.mx/files/Signature.zip (http://dedndave.x10.mx/files/Signature.zip)

the nice thing is, that we managed to collect a lot of data from forum members
so - it's not just the program that's useful, but all the replies from those who posted results
you can see what values are returned by a variety of processors...

http://www.masmforum.com/board/index.php?topic=13044.0 (http://www.masmforum.com/board/index.php?topic=13044.0)

at the moment, it's been downloaded 286 times   :lol:
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 23, 2014, 09:04:54 AM
Quote from: MichaelW on February 23, 2014, 04:15:17 AM
Mark,

I compiled your source from the first post in this thread with the VC++ Toolkit 2003 compiler, no problems, but a warning with /W3:

CPUInfo.c(153) : warning C4244: '=' : conversion from 'long' to 'short', possible loss of data

Running the exe on my P3 I get:

Extended + family ID: 06
Extended + model ID: 07
Stepping: 3
Microarchiture: Unknown

CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU does not have SSE2.
CPU does not have SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.


All correct AFAIK, but when I run it on my 3.06GHz P4 Northwood (the first P4 with HT) I get:

Extended + family ID: 0f
Extended + model ID: 02
Stepping: 9
Unknown microarchitecture
CPU has FP unit.
CPU has MMX.
CPU has SSE.
CPU has SSE2.
CPU has SSE3.
CPU does not have SSE 4.1.
CPU does not have SSE 4.2.
CPU does not have AVX.


AFAIK the SSE3 is not correct, and as a test, since I don't have any MASM version that can assemble SSE3 instructions set up, I assembled and linked this source with as/ld (no as warnings or errors):

.intel_syntax noprefix
.section .text
    lddqu xmm0, X
    ret
.section .data
.balign 16
X:
.octa 0


And running the exe on both systems I get exception number c000001eh, which per ntstatus.h is STATUS_INVALID_LOCK_SEQUENCE. But I suspect that this is not conclusive proof, because I seem to recall something about the OS needing to enable instruction set extensions.
I think you might be right. I seem to recall something saying that even though a particular technology was supported in the CPU, it also had to be supported in the OS. It might have been in the Intel Optimization reference, although I've been looking at some stuff by Agner Fog and it might have been in there.
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 23, 2014, 09:06:20 AM
Quote from: dedndave on February 23, 2014, 06:47:28 AM
Mark,
some time back, i wrote a test program that you may find useful

in the process of writing the code, i corrected some errors that were in the Intel manuals
i also added the AMD processors (at that time) to create a single BMP file

http://dedndave.x10.mx/files/Signature.zip (http://dedndave.x10.mx/files/Signature.zip)

Thanks, dedndave. I have tucked this away for future reference.
Quote from: dedndave
the nice thing is, that we managed to collect a lot of data from forum members
so - it's not just the program that's useful, but all the replies from those who posted results
you can see what values are returned by a variety of processors...

http://www.masmforum.com/board/index.php?topic=13044.0 (http://www.masmforum.com/board/index.php?topic=13044.0)

at the moment, it's been downloaded 286 times   :lol:
Title: Re: My version of a CPU identification utility
Post by: Gunther on February 23, 2014, 11:00:57 AM
Hi Dave,

Quote from: dedndave on February 23, 2014, 06:47:28 AM
at the moment, it's been downloaded 286 times   :lol:

that's no longer up-to-date.  :lol: :lol: :lol: Here is the output:

          EAX: 0
          ECX: 120
          EDX: 00403AB0h
       cbSize: 120
dwCoreAffMask: 00000000000000000000000000000001b
dwIdCpuStatus: 00000000h
    bVendorID: 1
      bFamily: 6
   bExtFamily: 0
       bModel: 10
    bExtModel: 3
        bType: 0
        bStep: 9
     bMmxBits: 00000001b
   w3DNowBits: 0000000000000000b
     wSseBits: 0000000000111111b
   dwMiscBits: 00000000000100001011101111111111b
      szBrand: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
     szVendor: GenuineIntel
        szMmx: MMX
      sz3DNow:
        szSse: SSE4.2
Press any key to continue ...


Gunther
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 23, 2014, 06:08:55 PM
Here is an updated version, addressing some of the problems noted in this thread.

I added the architectures listed in the 2007 Intel docs (optimization reference), and fixed a bug where I picked an incorrect bit when checking for CPU support for AVX. The new code also does the right thing in checking for AVX support, by looking for support from both the CPU and the OS.

For those of you who modified my code for gcc, this code still has inline assembly. Here are the things I changed.

Changes in printCpuidData function:
1. Added a variable called OSXSAVE.
2. Added a couple of cases for family ID 6.
3. Added logic for family ID 15.
4. Corrected the bit extracted to determine CPU support for AVX.
5. Added logic to extract the bit for OSXSAVE.
6. Revised the logic to determine OS and CPU support for AVX.

Added AVXSupportInOS function - mostly inline assembly that calls XGETBV with ECX = 0. If bits 1 and 2 of EAX are set, XMM state and YMM State are supported in the OS.
Title: Re: My version of a CPU identification utility
Post by: TWell on February 23, 2014, 09:42:02 PM
Processor name too?char *cpu_name(char *name)
{
__asm{
push ebx
mov edi, dword ptr name
mov dword ptr [edi], 0
mov eax, 80000000h
cpuid
cmp eax, 80000000h
jna pass
mov eax, 80000002h
cpuid
mov dword ptr [edi], eax
mov dword ptr [edi+4], ebx
mov dword ptr [edi+8], ecx
mov dword ptr [edi+12], edx
mov eax, 80000003h
cpuid
mov dword ptr [edi+16], eax
mov dword ptr [edi+20], ebx
mov dword ptr [edi+24], ecx
mov dword ptr [edi+28], edx
mov eax, 80000004h
cpuid
mov dword ptr [edi+32], eax
mov dword ptr [edi+36], ebx
mov dword ptr [edi+40], ecx
mov dword ptr [edi+44], edx
pass:
pop ebx
}
return name;
}

char s[50];
printf("cpu name: %s\n", cpu_name(s));
shorterchar *cpu_name(char *name)
{
int idx;
__asm{
push ebx
mov edi, name
mov dword ptr [edi], 0
mov eax, 80000000h
cpuid
cmp eax, 80000004h
jb pass
mov idx, 80000002h
next:
mov eax, idx
cpuid
mov dword ptr [edi], eax
mov dword ptr [edi+4], ebx
mov dword ptr [edi+8], ecx
mov dword ptr [edi+12], edx
add edi, 16
add idx, 1
cmp idx, 80000004h
jna next
pass:
pop ebx
}
return name;
}
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 24, 2014, 05:20:56 AM
Tim,
That would be easy enough to add. I didn't include this information in the original code, thinking that the microarchitecture would be enough. As it turns out, the microarchitecture is a relatively new descriptor that started somewhere around the P6 time. (I could be wrong about this.) 

Anyway, I'll incorporate your code into the utility and repost it shortly.
Mark
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 24, 2014, 11:35:33 AM
;--------------------------------------------------

BrandStr PROC

    mov     eax,80000000h
    push    ebx
    cpuid
    push    eax
    .if eax>=80000004h
        push    edi
        mov     edi,3
        push    0A0Dh
        .repeat
            lea     eax,[edi+80000001h]
            cpuid
            push    edx
            push    ecx
            push    ebx
            push    eax
            dec     edi
        .until ZERO?
        mov     edi,esp
        mov     al,20h
        mov     ecx,48
        repz    scasb
        dec     edi
        print   edi
        add     esp,52
        pop     edi
    .endif
    pop     eax
    pop     ebx
    ret

BrandStr ENDP

;--------------------------------------------------


EDIT: added code to verify brand string is supported
also, returns maximum supported extended function in EAX
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 24, 2014, 06:36:52 PM
dedndave, I've incorporated your earlier code and restructured my code, as some of the functions were getting pretty long. I'll need to digest the latest contribution, but will add it into the mix tomorrow.

Thanks!

Mark
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 24, 2014, 11:35:49 PM
it's simple code to display the brand string
the brand string quite often has numerous leading spaces - so, they are stripped off
here's a little demo program...
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 25, 2014, 01:20:38 AM
i see a little boo boo in my thinking, though
i pushed 0A0Dh onto the stack, thinking i'd get a carriage return/line feed
but - the string is typically null terminated, so that never gets displayed   :P
you can just push a 0
Title: Re: My version of a CPU identification utility
Post by: jj2007 on February 25, 2014, 02:17:19 AM
Quote from: dedndave on February 25, 2014, 01:20:38 AM
you can just push a 0

; no push
        print   edi, 13, 10
        add     esp,52-4

Title: Re: My version of a CPU identification utility
Post by: Gunther on February 25, 2014, 03:33:40 AM
Jochen,

Quote from: jj2007 on February 25, 2014, 02:17:19 AM
; no push
        print   edi, 13, 10
        add     esp,52-4[/tt]


:t

Gunther
Title: Re: My version of a CPU identification utility
Post by: TWell on February 25, 2014, 03:51:38 AM
Just lucky, if this works?
;CPUName.asm
.586
.MODEL FLAT, STDCALL
OPTION CASEMAP :NONE

INCLUDELIB kernel32.lib
ExitProcess PROTO :DWORD

INCLUDELIB user32.lib
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD

CPUString PROTO buf:DWORD

.data
sApp db "CPUName",0

.data?
sCpu db 100 DUP(?)

.code
start PROC
mov eax, 0
cpuid
mov DWORD PTR sCpu, ebx
mov DWORD PTR sCpu+4, edx
mov DWORD PTR sCpu+8, ecx
mov DWORD PTR sCpu+12, 0A0Dh
INVOKE CPUString, ADDR sCpu+14
INVOKE MessageBoxA, 0, ADDR sCpu, ADDR sApp, 0
INVOKE ExitProcess,0
start ENDP

CPUString PROC USES edi ebx, buf:DWORD
LOCAL idx:DWORD
mov edi, buf
mov dword ptr [edi], 0
mov eax, 80000000h
cpuid
cmp eax, 80000004h
jb pass
mov idx, 80000002h
next:
mov eax, idx
cpuid
mov dword ptr [edi], eax
mov dword ptr [edi+4], ebx
mov dword ptr [edi+8], ecx
mov dword ptr [edi+12], edx
add edi, 16
add idx, 1
cmp idx, 80000004h
jna next
pass:
ret
CPUString ENDP

END start
Title: Re: My version of a CPU identification utility
Post by: GoneFishing on February 25, 2014, 04:04:40 AM
Quote from: TWell on February 25, 2014, 03:51:38 AM
Just lucky, if this works?
Compiled after some minor changes( name -> _name etc.)
APPCRASH :
Quote
  Exception Code:   80000003
  Exception Offset:   0000108d
Title: Re: My version of a CPU identification utility
Post by: TWell on February 25, 2014, 04:26:05 AM
least missing ret.
name changed to buf.
.586 inserted
Title: Re: My version of a CPU identification utility
Post by: GoneFishing on February 25, 2014, 05:53:52 AM
It works after adding RET  :t
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 26, 2014, 05:12:30 AM
In the attached version (source file and release exe), the code now prints the processor name, together with the Intel microarchitecture, if it's one that I know about (i.e., was listed in the current and 2007 Intel Optimization references). I also found and fixed a bug where the code mistakenly reused the SSE2 bit to indicate the presence of SSE3.

Unfortunately for some of you, my code still has inline assembly.

One thing that I had trouble with was trying to allocate heap memory for a couple of strings. When I allocated them with either malloc() or calloc(), I couldn't free() the pointers without generating a bad pointer exception. Things worked fine if I didn't try to free the pointers, but it's not good practice to allocate heap storage without freeing it when you're done. All this was happening with VS 10. I was able to workaround the problem by using _malloca() and _freea, but I have no idea why the older run-time library functions were acting up.

Below are the functions that contain inline assembly, together with a summary of how much or how little they changed.

cpu_info function - unchanged from before except for description comment.
// Get version and feature information from cpuid, leaf EAX = 1.
void cpu_info(struct CpuData *returnData)
{
__asm{
push ebx
mov eax, 1H
cpuid
mov ebx, returnData
; After the call to cpuid, store EAX, ECX, and EDX in the CpuData struct.
mov (dword ptr [ebx]).eaxReg, eax
mov (dword ptr [ebx]).ecxReg, ecx
mov (dword ptr[ebx]).edxReg, edx
pop ebx
}

}

printCpuidData function - logic changed extensively.
// Now check for support for AVX2.
// Can't check for AVX2 unless the CPU supports AVX.
if (AVX && OSXSAVE && (OSFlags & 0x6))
{

// Call cpuid with EAX = 7 and ECX = 0.
// If bit 5 in the returned EBX is 1, AVX2 is supported.
__asm{
push eax
push ecx
mov eax, 7
xor ecx, ecx
cpuid
mov cacheEBX, ebx
pop ecx
pop eax
}
AVX2 = (cacheEBX & 0x20) >> 5;
printf("CPU and OS %s AVX2.\n", AVX2 ? "support" : "do not support");
}
else printf("CPU and OS do not support AVX2.\n");

AVXSupportInOS function - no change.
int AVXSupportInOS()
{
// Read the contents of the extended control register (XCR) specified
// in the ECX register.
// Currently, only XCR0 is supported, so set ECX to zero before
// executing xgetbv (get value of extended control register.
// If bits 1 and 2 are set, XMM state and YMM state are enabled by the OS.
int OSFlags;
__asm{
xor ecx, ecx
xgetbv 
mov OSFlags, eax
}
return OSFlags;
}


cpu_name function - This is new, and is based on the code that TWell and dedndave contributed in this thread.
void cpu_name(char *name)
{
__asm{
push ebx
mov edi, dword ptr name
mov dword ptr [edi], 0
mov eax, 80000000h
cpuid
cmp eax, 80000004h  ; If eax < 80000004h, processor name isn't supported.
jna pass

xor esi, esi
loop1:
lea eax, [esi + 80000002h]
cpuid
mov dword ptr [edi], eax
mov dword ptr [edi+4], ebx
mov dword ptr [edi+8], ecx
mov dword ptr [edi+12], edx
add edi, 16
inc esi
cmp esi, 3
jb loop1

pass:
pop ebx
}
}


Title: Re: My version of a CPU identification utility
Post by: dedndave on February 26, 2014, 05:28:36 AM
all looks correct, here

prescott w/htt
Processor name: Intel(R) Pentium(R) 4 CPU 3.00GHz
Extended + family ID: 0f
Extended + model ID: 04
Stepping: 3
Microarchitecture: NetBurst
CPU has FP unit.
CPU supports MMX.
CPU supports SSE.
CPU supports SSE2.
CPU supports SSE3.
CPU does not support SSE 4.1.
CPU does not support SSE 4.2.
CPU does not support AVX.
CPU and OS do not support AVX2.


you might add a line for SSSE3
also, some AMD processors have 3DNow! and 3DNow!+
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 26, 2014, 06:24:28 AM
dedndave,
Checking for SSSE3 is pretty simple - bit 9 in the returned ECX register from cpuid.

As far as AMD features go, neither of my two computers has an AMD processor, so I haven't been including any tests for those features.
Title: Re: My version of a CPU identification utility
Post by: TWell on February 26, 2014, 06:28:07 AM
Processor name: AMD Athlon(tm) II X2 220 Processor
Extended + family ID: 1f
Extended + model ID: 06
Stepping: 3
Microarchitecture: Unknown
CPU has FP unit.
CPU supports MMX.
CPU supports SSE.
CPU supports SSE2.
CPU supports SSE3.
CPU does not support SSE 4.1.
CPU does not support SSE 4.2.
CPU does not support AVX.
CPU and OS do not support AVX2.
Title: Re: My version of a CPU identification utility
Post by: MichaelW on February 26, 2014, 06:30:18 AM
Dave,

Have you tried executing any SSE3 instructions?
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 26, 2014, 08:51:44 AM
SSE3, yes
SSSE3, no - not supported on my processor
Title: Re: My version of a CPU identification utility
Post by: fearless on February 26, 2014, 10:34:10 AM
Any way to get the correct amount of physical cores?

I had tried using the following code, but for my i5 3570K it returns too many for logical cores 16 and physical cores 8. Im not sure if this is some issue with hyperthreading or some other issue i havent identified. Im assuming if it is hyperthreading, then logical should be 8 and physical should be 4.

        mov eax, 1
        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx
        cpuid
        and ebx, 000FF0000h
        shr ebx, 16
        mov LogicalCores, ebx


         mov eax, 4
        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx
        cpuid
        and eax, 0FC000000h; 11111100000000000000000000000000b  ; bits 26-31
        shr eax, 26
        inc eax
        mov PhysicalCores, eax
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 26, 2014, 11:12:28 AM
easiest way.....

use GetProcessAffinityMask and count bits
it's only fully valid for machines with 32 cores or less   ::)
as far as i know - the most made so far is 24 cores

    INVOKE  GetModuleHandle,NULL
    push    eax
    mov     ecx,esp
    push    eax
    mov     edx,esp
    INVOKE  GetProcessAffinityMask,eax,edx,ecx
    pop     ecx
    pop     edx
    bsr     eax,edx
    inc     eax

Title: Re: My version of a CPU identification utility
Post by: dedndave on February 26, 2014, 11:22:21 AM
oh - that returns the number of logical cores
to get the number of physical cores....
for AMD processors, physical count = logical count
for Intel processors, divide by 2 if HTT bit is set
Title: Re: My version of a CPU identification utility
Post by: Mark44 on February 26, 2014, 12:49:07 PM
timppa,
Try this version on your AMD Athlon machine... I added a small amount of code to test for SSSE3.

Dave,
That bsr in your code threw me for a minute. I thought it was Branch to Subroutine, which if memory serves, is a Motorola 68x00 instruction. I had to look it up to find out that it's bit scan reverse.

Mark
Title: Re: My version of a CPU identification utility
Post by: dedndave on February 26, 2014, 01:18:20 PM
works here - SSSE3 not supported
Title: Re: My version of a CPU identification utility
Post by: TWell on February 26, 2014, 05:33:30 PM
Quote from: Mark44 on February 26, 2014, 12:49:07 PM
timppa,
Try this version on your AMD Athlon machine... I added a small amount of code to test for
Processor name: AMD Athlon(tm) II X2 220 Processor
Extended + family ID: 1f
Extended + model ID: 06
Stepping: 3
Microarchitecture: Unknown
CPU has FP unit.
CPU supports MMX.
CPU supports SSE.
CPU supports SSE2.
CPU supports SSE3.
CPU does not support SSSE3.
CPU does not support SSE 4.1.
CPU does not support SSE 4.2.
CPU does not support AVX.
CPU and OS do not support AVX2.
Title: Re: My version of a CPU identification utility
Post by: jj2007 on February 26, 2014, 06:52:19 PM
Processor name: AMD Athlon(tm) Dual Core Processor 4450B
Extended + family ID: 0f
Extended + model ID: 6b
Stepping: 2
Microarchitecture: Unknown
CPU has FP unit.
CPU supports MMX.
CPU supports SSE.
CPU supports SSE2.
CPU supports SSE3.
CPU does not support SSSE3.
CPU does not support SSE 4.1.
CPU does not support SSE 4.2.
CPU does not support AVX.
CPU and OS do not support AVX2.