detailed CPUID values

Share your advanced PureBasic knowledge/code with the community.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

detailed CPUID values

Post by doctorized »

There are many topics about cpuid instruction to take cpu name, serial, or whatever, but there is no complete
procedure to show all the cpuid values from all cores.

Code: Select all

Global dwEBX.l = 0, dwECX.l = 0, dwEDX.l = 0, dwEAX.l = 0
Global processorID.s{12}
Global PhysicalCoreNum.l
Global Dim CIF.l(264), Dim EAX.l(264), Dim EBX.l(264), Dim ECX.l(264), Dim EDX.l(264)

Procedure.l CPUID(Array CIF.l(1), Array EAXval.l(1), Array EBXval.l(1), Array ECXval.l(1), Array EDXval.l(1))

	j.l = -1: i.l = 0: tmp.l = 0: MaxCPUID.l
	
   ! mov eax,0               ; function 0 = manufacturer string
   ! cpuid
   ! mov DWORD [v_processorID+0],ebx  
   ! mov DWORD [v_processorID+4],edx
   ! mov DWORD [v_processorID+8],ecx
	If processorID = "AuthenticAMD"
		! mov eax, $80000008      ; get extended flags
      ! CPUID
		! mov dword [v_PhysicalCoreNum],ecx
		PhysicalCoreNum & $FF
	Else
		! mov		eax, 04
		! mov		ecx, 00
		! CPUID
		! shr		eax, 26
		! and		eax, $3F
		! mov		DWORD [v_PhysicalCoreNum], eax
	EndIf
	
For tmpi.l=0 To PhysicalCoreNum
	SetThreadAffinityMask_(GetCurrentThread_(), 1 << tmpi);tell the system which core will do the job.
	j + 1
	CIF(j) = $12345678; dummy value.
	j + 1
	EnableASM
		mov eax,0
		! CPUID
		mov dword [v_dwEAX], eax
		mov dword [v_dwEBX], ebx
		mov dword [v_dwECX], ecx
		mov dword [v_dwEDX], edx
	DisableASM

	MaxCPUID = dwEAX & $FFFFFFFF
	CIF(j) = 0
	EAX(j) = dwEAX
	EBX(j) = dwEBX
	ECX(j) = dwECX
	EDX(j) = dwEDX;
	
	If (MaxCPUID>=4)
		For i=1 To 3
			j + 1
			EnableASM
				mov eax,i
				! CPUID
				mov dword [v_dwEAX], eax
				mov dword [v_dwEBX], ebx
				mov dword [v_dwECX], ecx
				mov dword [v_dwEDX], edx
			DisableASM
			CIF(j) = i
			EAX(j) = dwEAX
			EBX(j) = dwEBX
			ECX(j) = dwECX
			EDX(j) = dwEDX
		Next
cpuidagain:		
		EnableASM
			mov ecx, tmp
			mov eax, 4
			! CPUID
			;push eax
			And al, $1F
			cmp al, 0
			;pop eax
			je l_cpuid5next

			mov dword [v_dwEAX], eax
			mov dword [v_dwEBX], ebx
			mov dword [v_dwECX], ecx
			mov dword [v_dwEDX], edx
		DisableASM
			j + 1
			tmp + 1 
			CIF(j) = 4;
			EAX(j) = dwEAX;
			EBX(j) = dwEBX;
			ECX(j) = dwECX;
			EDX(j) = dwEDX;
			Goto cpuidagain;
		
cpuid5next:
		If MaxCPUID>=5
			For i=5 To MaxCPUID
				j+1
				EnableASM
					mov eax,i
					! CPUID
					mov dword [v_dwEAX], eax
					mov dword [v_dwEBX], ebx
					mov dword [v_dwECX], ecx
					mov dword [v_dwEDX], edx
				DisableASM
				CIF(j) = i;
				EAX(j) = dwEAX;
				EBX(j) = dwEBX;
				ECX(j) = dwECX;
				EDX(j) = dwEDX;
			Next
		EndIf
	Else
	For i=1 To MaxCPUID
		j+1
		EnableASM
			mov eax,i
			! CPUID
			mov dword [v_dwEAX], eax
			mov dword [v_dwEBX], ebx
			mov dword [v_dwECX], ecx
			mov dword [v_dwEDX], edx
		DisableASM
		CIF(j) = i;
		EAX(j) = dwEAX;
		EBX(j) = dwEBX;
		ECX(j) = dwECX;
		EDX(j) = dwEDX;
	Next
	EndIf
	EnableASM
		mov eax, $80000000
		! CPUID
		mov dword [v_dwEAX], eax
	DisableASM
	If dwEAX & $FFFFFFFF > $80000000 And dwEAX < 0
		MaxCPUID = dwEAX
		For i=$80000000 To MaxCPUID
			j+1
			EnableASM
				mov eax,i
				! CPUID
				mov dword [v_dwEAX], eax
				mov dword [v_dwEBX], ebx
				mov dword [v_dwECX], ecx
				mov dword [v_dwEDX], edx
			DisableASM
			CIF(j) = i;
			EAX(j) = dwEAX;
			EBX(j) = dwEBX;
			ECX(j) = dwECX;
			EDX(j) = dwEDX;
		Next
	EndIf
	EnableASM
		mov eax,$80860000
		! CPUID
		mov dword [v_dwEAX], eax
	DisableASM
	If dwEAX & $FFFFFFFF > $80860000 And dwEAX < 0
		MaxCPUID = dwEAX
		For i= $80860000 To MaxCPUID
			j+1
			EnableASM
				mov eax,i
				! CPUID
				mov dword [v_dwEAX], eax
				mov dword [v_dwEBX], ebx
				mov dword [v_dwECX], ecx
				mov dword [v_dwEDX], edx
			DisableASM
			CIF(j) = i;
			EAX(j) = dwEAX;
			EBX(j) = dwEBX;
			ECX(j) = dwECX;
			EDX(j) = dwEDX;
		Next
	EndIf
	EnableASM
		mov eax,$C0000000
		! CPUID
		mov dword [v_dwEAX], eax
	DisableASM
	If dwEAX & $FFFFFFFF > $C0000000 And dwEAX < 0
		MaxCPUID = dwEAX
		For i= $C0000000 To MaxCPUID
			j+1
			EnableASM
				mov eax,i
				! CPUID
				mov dword [v_dwEAX], eax
				mov dword [v_dwEBX], ebx
				mov dword [v_dwECX], ecx
				mov dword [v_dwEDX], edx
			DisableASM
			CIF(j) = i;
			EAX(j) = dwEAX;
			EBX(j) = dwEBX;
			ECX(j) = dwECX;
			EDX(j) = dwEDX;
		Next
	EndIf
Next
	ProcedureReturn 1;
EndProcedure

Procedure.s Convert2Char(value.l)
char.s=RSet(Hex(value),8,"0")
If Asc(Mid(char, 1, 1)) > 58 :
	tmp1 = (Asc(Mid(char, 1, 1)) - 55) * 16 
Else
	tmp1 = (Asc(Mid(char, 1, 1)) - 48) * 16 
EndIf
If Asc(Mid(char, 2, 1)) > 58 
	tmp1 = tmp1 + Asc(Mid(char, 2, 1)) - 55 
Else 
	tmp1 = tmp1 + Asc(Mid(char, 2, 1)) - 48
EndIf
If Asc(Mid(char, 3, 1)) > 58
	tmp2 = (Asc(Mid(char, 3, 1)) - 55) * 16
Else
	tmp2 = (Asc(Mid(char, 3, 1)) - 48) * 16
EndIf
If Asc(Mid(char, 4, 1)) > 58
	tmp2 = tmp2 + Asc(Mid(char, 4, 1)) - 55
Else
	tmp2 = tmp2 + Asc(Mid(char, 4, 1)) - 48
EndIf
If Asc(Mid(char, 5, 1)) > 58
	tmp3 = (Asc(Mid(char, 5, 1)) - 55) * 16
Else
	tmp3 = (Asc(Mid(char, 5, 1)) - 48) * 16
EndIf
If Asc(Mid(char, 6, 1)) > 58
	tmp3 = tmp3 + Asc(Mid(char, 6, 1)) - 55
Else
	tmp3 = tmp3 + Asc(Mid(char, 6, 1)) - 48
EndIf
If Asc(Mid(char, 7, 1)) > 58
	tmp4 = (Asc(Mid(char, 7, 1)) - 55) * 16
Else
	tmp4 = (Asc(Mid(char, 7, 1)) - 48) * 16
EndIf
If Asc(Mid(char, 8, 1)) > 58
	tmp4 = tmp4 + Asc(Mid(char, 8, 1)) - 55
Else
	tmp4 = tmp4 + Asc(Mid(char, 8, 1)) - 48
EndIf
If tmp1 = 0: tmp1 = 32 : EndIf
If tmp2 = 0: tmp2 = 32 : EndIf
If tmp3 = 0: tmp3 = 32 : EndIf
CharConv.s = Chr(tmp1) + Chr(tmp2) + Chr(tmp3) + Chr(tmp4)
ProcedureReturn CharConv
EndProcedure

i.l = CPUID(CIF(),EAX(),EBX(),ECX(),EDX())

If OpenWindow(10,0,0,650,470, "CPUID values", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ListIconGadget(0, 15, 15, 620, 450, "Function",80,#PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
    AddGadgetColumn(0,1,"Register",100)
    AddGadgetColumn(0,2,"Binary value",220)
    AddGadgetColumn(0,3,"Hex value",100)
    AddGadgetColumn(0,4,"Value in letters",99)
EndIf
*Quit = #False

i = CPUID(CIF(),EAX(),EBX(),ECX(),EDX())
					For i=0 To 264
						If CIF(i) = 0 And EAX(i)=0 And EBX(i)=0 And ECX(i)=0
							Break
						EndIf
						If CIF(i) = $12345678
							AddGadgetItem(0,-1, "Core #" + Str(iCore))
							SetGadgetItemColor(0,(iii)*5 + iCore*2,#PB_Gadget_FrontColor,$FF0000,0)
							AddGadgetItem(0,-1, "")
							iCore + 1
						Else
							iii + 1
							tmp.s = RSet(Bin(EAX(i) & $FFFFFFFF),32,"0")
							tmp1.s = Left(tmp,8) + "-" + Mid(tmp,9,8) + "-" + Mid(tmp,17,8) + "-" + Mid(tmp,25,8)
							tmp = RSet(Bin(EBX(i) & $FFFFFFFF),32,"0")
							tmp2.s = Left(tmp,8) + "-" + Mid(tmp,9,8) + "-" + Mid(tmp,17,8) + "-" + Mid(tmp,25,8)
							tmp = RSet(Bin(ECX(i) & $FFFFFFFF),32,"0")
							tmp3.s = Left(tmp,8) + "-" + Mid(tmp,9,8) + "-" + Mid(tmp,17,8) + "-" + Mid(tmp,25,8)
							tmp = RSet(Bin(EDX(i) & $FFFFFFFF),32,"0")
							tmp4.s = Left(tmp,8) + "-" + Mid(tmp,9,8) + "-" + Mid(tmp,17,8) + "-" + Mid(tmp,25,8)	
							tmp5.s = Hex(CIF(i))
							If Len(tmp5) > 8:tmp5 = Right(tmp5,8): EndIf	
							AddGadgetItem(0,-1, RSet(tmp5,8,"0") + Chr(10) + "EAX" +Chr(10) + tmp1 + Chr(10) + RSet(Hex(EAX(i) & $FFFFFFFF),8,"0") + Chr(10) + Convert2Char(EAX(i)))
							AddGadgetItem(0,-1, "" + Chr(10) + "EBX" +Chr(10) + tmp2 + Chr(10) + RSet(Hex(EBX(i) & $FFFFFFFF),8,"0") + Chr(10) + Convert2Char(EBX(i)))
							AddGadgetItem(0,-1, "" + Chr(10) + "ECX" +Chr(10) + tmp3 + Chr(10) + RSet(Hex(ECX(i) & $FFFFFFFF),8,"0") + Chr(10) + Convert2Char(ECX(i)))
							AddGadgetItem(0,-1, "" + Chr(10) + "EDX" +Chr(10) + tmp4 + Chr(10) + RSet(Hex(EDX(i) & $FFFFFFFF),8,"0") + Chr(10) + Convert2Char(EDX(i)))
							AddGadgetItem(0,-1, "")
						EndIf
					Next
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      *Quit = #True
  EndSelect
Until *Quit
moogle
Enthusiast
Enthusiast
Posts: 372
Joined: Tue Feb 14, 2006 9:27 pm
Location: London, UK

Re: detailed CPUID values

Post by moogle »

Quite nice!

All the strings are in reverse, but I'm guessing it's because they were all in hex :D
Image
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: detailed CPUID values

Post by doctorized »

moogle wrote:All the strings are in reverse, but I'm guessing it's because they were all in hex :D
That's the way they are coming from the cpu.
moogle
Enthusiast
Enthusiast
Posts: 372
Joined: Tue Feb 14, 2006 9:27 pm
Location: London, UK

Re: detailed CPUID values

Post by moogle »

doctorized wrote:
moogle wrote:All the strings are in reverse, but I'm guessing it's because they were all in hex :D
That's the way they are coming from the cpu.
Oh ic, I thought it was like that because when I did some packet editing in a game I played I had to reverse the hex values :lol:

Still nice code, could help someone make their own CPU-Z.
Image
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: detailed CPUID values

Post by SFSxOI »

doctorized wrote:
moogle wrote:All the strings are in reverse, but I'm guessing it's because they were all in hex :D
That's the way they are coming from the cpu.
?????????

Mine don't come reversed when I use WMI to do it.
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: detailed CPUID values

Post by doctorized »

SFSxOI wrote:Mine don't come reversed when I use WMI to do it.
As you see, processorID.s has the vendor's id normal, I do not write "htuAitneDMAc" (htuA itne DMAc) for AuthenticAMD
as I see in the registers of my Phenom II.
Post Reply