News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Quick CPU info based on CPUID

Started by jj2007, February 11, 2009, 11:27:32 AM

Previous topic - Next topic

herge


Hi jj2207:

Nice program!
Is rhey any place we can get instructions spec on CPUID.
I am having alsorts of problems wirh it in windbg.

Regards herge
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

Tedd

The Intel and AMD manuals contain all the info for CPUID.
No snowflake in an avalanche feels responsible.

ToutEnMasm


There is something simple to use,a dos window

Quote
NUMBER_OF_PROCESSORS=1
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=15
PROCESSOR_REVISION=0401
ProgramFiles=C:\Program Files

direct access can be made by GetEnvironmentStrings
It is made for each program by the system;speed and easy
registry can also give that,but it is slower
CPUID answer to many questions,with help of the manuals (intel amd) but need some headers define.





Bill Cravener

Nice gadget jj.

C:\Temp>cpuid short

              Intel(R) Pentium(R) D CPU 2.80GHz (SSE3)

C:\Temp>cpuid full

This is your CPU:
Model           6
Family          15
Step            4
Manufacturer    GenuineIntel
Description     Intel Pentium dual-core x64, SSE3
Brand name      Intel(R) Pentium(R) D CPU 2.80GHz

C:\Temp>
My MASM32 Examples.

"Prejudice does not arise from low intelligence it arises from conservative ideals to which people of low intelligence are drawn." ~ Isaidthat

jj2007

Quote from: ToutEnMasm on March 23, 2009, 01:39:16 PM

There is something simple to use,a dos window

Quote
NUMBER_OF_PROCESSORS=1
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=15
PROCESSOR_REVISION=0401
ProgramFiles=C:\Program Files


Very simple, but how can I tell my code if the CPU supports SSE2, using this info?
And how do I get the brand name, e.g. " Intel(R) Pentium(R) 4 CPU 3.40GHz (SSE3)"?

ToutEnMasm


I was not saying that you can have all the needed informations as this.
it's a very interesting way to have informations,that all.
Quote
direct access can be made by GetEnvironmentStrings
It is made for each program by the system;speed and easy
registry can also give that,but it is slower
CPUID answer to many questions,with help of the manuals (intel amd) but need some headers define.

There is one,in particular,that isn't shown by your prog.

Quote
NUMBER_OF_PROCESSORS=1


Mark Jones

Just an idea, but how about setting up a SEH chain and actually testing an instruction from each extension? MMX, SSE, etc.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

PBrennick

While I _do_ think this is a great approach in this discussion be warned that if you code such a handler you will be a prime candidate for generating false positives as this is a popular method used by those dispicable persons to code their trash. It is an extremely easy way of diverting code execution to your own control and blah, blah, blah ...

... and everyone will think it contains a virus.
Paul
The GeneSys Project is available from:
The Repository or My crappy website

Tedd

Because eflags and a few cpuid 'calls' gets you everything and a whole lot more than you'd want to print.
SEH would be quite a bit of overhead for this, especially when the 'information gathering' is pretty simple and linear.
No snowflake in an avalanche feels responsible.

PBrennick

Of course you are correct, Tedd, but I think the idea is to come up with another way besides using CPUID because it works inconsistantly across all machines. I, personally, do not know if there IS a better way but I think playing with the idea may be a great adventure for all of us.

Any ideas, JJ? I am certain you have been investigating this.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

ToutEnMasm


Perhaps some define masks could help

Quote
MaximumReturnValue equ 0      ;in eax,return max value accepted by eax
;cpuid with eax == 1   
cpu_ecx_SSE3 equ 1 SHL 0
cpu_ecx_reserved1 equ 1 SHL 1
cpu_ecx_reserved2 equ 1 SHL 2      
cpu_ecx_reserved3 equ 1 SHL 3      
cpu_ecx_DS_CPL equ 1 SHL 4      
cpu_ecx_VMX equ 1 SHL 5      
cpu_ecx_SMX equ 1 SHL 6      
cpu_ecx_EST equ 1 SHL 7      
cpu_ecx_TM2 equ 1 SHL 8      
cpu_ecx_SSSE3 equ 1 SHL 9      
cpu_ecx_CNXT_ID equ 1 SHL 10      
cpu_ecx_reserved11 equ 1 SHL 11      
cpu_ecx_reserved12 equ 1 SHL 12
cpu_ecx_CMPXCHG16B equ 1 SHL 13      
cpu_ecx_xTPR_Update equ 1 SHL 14      
cpu_ecx_PDCM equ 1 SHL 15
cpu_ecx_reserved16 equ 1 SHL 16      
cpu_ecx_reserved17 equ 1 SHL 17      
cpu_ecx_DCA equ 1 SHL 18      
cpu_ecx_SSE4_1 equ 1 SHL 19      
cpu_ecx_SSE4_2 equ 1 SHL 20      
cpu_ecx_x2APIC equ 1 SHL 21
cpu_ecx_MOVBE equ 1 SHL 22      
cpu_ecx_POPCNT equ 1 SHL 23      
cpu_ecx_Reserved24 equ 1 SHL 24      
cpu_ecx_Reserved25 equ 1 SHL 25      
cpu_ecx_XSAVE equ 1 SHL 26      
cpu_ecx_OSXSAVE equ 1 SHL 27      
cpu_ecx_Reserved28 equ 1 SHL 28      
cpu_ecx_Reserved29 equ 1 SHL 29
cpu_ecx_Reserved30 equ 1 SHL 30      
cpu_ecx_Reserved31 equ 1 SHL 31      
;----------------------------------------
cpu_edx_FPU equ 1 SHL 0
cpu_edx_VME equ 1 SHL 1
cpu_edx_DE equ 1 SHL 2      
cpu_edx_PSE equ 1 SHL 3      
cpu_edx_TST equ 1 SHL 4      
cpu_edx_MSR equ 1 SHL 5      
cpu_edx_PAE equ 1 SHL 6      
cpu_edx_MCE equ 1 SHL 7      
cpu_edx_CX8 equ 1 SHL 8      
cpu_edx_APIC equ 1 SHL 9      
cpu_edx_Reserved10 equ 1 SHL 10      
cpu_edx_SEP equ 1 SHL 11      
cpu_edx_MTRR equ 1 SHL 12
cpu_edx_PGE equ 1 SHL 13      
cpu_edx_MCA equ 1 SHL 14      
cpu_edx_CMOV equ 1 SHL 15
cpu_edx_PAT equ 1 SHL 16      
cpu_edx_PSE_36 equ 1 SHL 17      
cpu_edx_PSN equ 1 SHL 18      
cpu_edx_CLFSH equ 1 SHL 19      
cpu_edx_Reserved20 equ 1 SHL 20      
cpu_edx_DS equ 1 SHL 21
cpu_edx_ACPI equ 1 SHL 22      
cpu_edx_MMX equ 1 SHL 23      
cpu_edx_FXSR equ 1 SHL 24      
cpu_edx_SSE equ 1 SHL 25      
cpu_edx_SSE2 equ 1 SHL 26      
cpu_edx_SS equ 1 SHL 27      
cpu_edx_HTT equ 1 SHL 28      
cpu_edx_TM equ 1 SHL 29
cpu_edx_Reserved30 equ 1 SHL 30      
cpu_edx_PBE equ 1 SHL 31      

sample
Quote
   mov eax,MaximumReturnValue ; is cpuid support the 1 function ?
   cpuid
   .if eax >= 1
      mov eax,1
      cpuid
      mov eax,0
      test edx,cpu_edx_SSE2
      jz @F
         mov eax,1   ;support of sse2
      @@:
      test ecx,cpu_ecx_POPCNT
      jz @F
         inc eax   ;support POCNT
      @@:
      
   .else      
      mov eax,0
   .endif





jj2007

#26
For most practical applications, these lines should be sufficient...

include \masm32\include\masm32rt.inc

.code

start:
print "Supports SSE"
call ChkSSE2
print str$(eax)
exit

ChkSSE2 proc ; exactly 40 bytes with global return variable, 39 for ret eax
pushad
push 1
pop eax
db 0Fh, 0A2h ; cpuid 1
xor eax, eax
xor esi, esi
bt edx, 25 ; edx bit 25, SSE1
adc eax, esi
bt edx, 26 ; edx bit 26, SSE2
adc eax, esi
bt ecx, esi ; ecx bit 0, SSE3 (esi=0)
adc eax, esi
bt ecx, 9 ; ecx bit 9, SSE4
adc eax, esi
mov [esp+32-4], eax ; popped eax will contain the counter
; mov CpuSSE, eax ; optional: global return variable
popad
ret
ChkSSE2 endp
end start ; thanks, Herge ;-)

herge

 Hi jj2007:

Here's how I get the Intel Brand String.

.data
IntelString equ Iebx;
Iebx    dd 0
Idcx    dd 0
Iecx    dd 0
          dd 0  ; Zero Bytes
.code
Genuine    proc uses esi ebx ecx
    xor eax, eax
    cpuid
    mov esi, offset IntelString
    mov DWORD ptr [ esi + 0 ], ebx ; "Gene"
    mov DWORD ptr [ esi + 4 ], edx ; "ineI"
    mov DWORD ptr [ esi + 8 ], ecx ; "ntel"
    invoke StdOut, ADDR IntelString
    ret
Genuine    endp


Regards herge
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

herge

 Hi jj2007:

Results from my computer.

Supports SSE4

P.S. you fogot the
end start

Regards herge
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

Ficko

I am using this type of chain per intel docu.
Can be extended to cover SSE II up.

regards,
Ficko

.model flat
; ===========================================================================
extrn _isse:byte
extrn _mmx:byte
extrn _processor:dword
.code
; Puts _isse = TRUE if ISSE Exists: _mmx = TRUE if MMX Exists and _processor = CPUID
; =============== S U B R O U T I N E =======================================
_getprocessor proc near public
;check_80386
   pushfd                     ; push original EFLAGS
   pop   eax                 ; get original EFLAGS
   mov   ecx, eax          ; save original EFLAGS
   xor   eax, 40000h      ; flip AC bit in EFLAGS
   push  eax                 ; save new EFLAGS value on stack
   popfd                      ; replace current EFLAGS value
   pushfd                     ; get new EFLAGS
   pop   eax                 ; store new EFLAGS in EAX
   xor   eax, ecx           ; can't toggle AC bit, processor=80386
   jz    end_cpu_type    ; jump if 80386 processor
   push  ecx
   popfd                      ; restore AC bit in EFLAGS first
;-------------------------------------------------------------------------------------
;check_80486              ; Intel486 processor check
                                 ; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
                                 ; which indicates the presence of a processor with the CPUID
                                 ; instruction.
   mov   eax, ecx          ; get original EFLAGS
   xor   eax, 200000h    ; flip ID bit in EFLAGS
   push  eax                 ; save new EFLAGS value on stack
   popfd                      ; replace current EFLAGS value
   pushfd                     ; get new EFLAGS
   pop   eax                 ; store new EFLAGS in EAX
   xor   eax, ecx            ; can't toggle ID bit,
   je    end_cpu_type    ; processor=80486
;-------------------------------------------------------------------------------------
;USE CPUID
   xor   eax, eax           ; CPUID level 0
   cpuid
   dec   eax                 ; make sure 1 is valid input for CPUID
   jb    Exit                  ; if not, jump to end
   xor   eax, eax
   inc   eax
   cpuid                      ; EDX = feature flag
   and   edx, 800000h  ; test bit 23 of feature flag
   shr   edx, 23
   mov   byte ptr ds:_mmx, dl
   xor   eax, eax
   inc   eax
   cpuid
   mov   dword ptr ds:_processor, eax ; Store processor family/model/step
   mov   esi, edx          ; Store features bits
   mov   eax, 80000000h
   cpuid
;-------------------------------------------------------------------------------------
                                ; Check which extended functions can be called
   cmp   eax, 80000001h    ; Extended Feature Bits
   jb    no_ISSE           ; jump if not supported
   mov   eax, 80000001h    ; Select function 0x80000001
   cpuid
   mov   edi, edx          ; Store extended features bits
   shr   esi, 25
   xchg  eax, esi
   and   al, 1
   jnz   ExISSE
   shr   edi, 22
   xchg  eax, edi
   and   al, 1
   jnz   ExISSE
no_ISSE: xor  eax, eax
   jmp   ExISSE
Exit:
   xor   eax, eax
end_cpu_type:
   mov   dword ptr ds:_processor, eax
   mov   byte ptr ds:_mmx, al
ExISSE:  mov  byte ptr ds:_isse, al
   ret 
_getprocessor endp
end