Page 1 sur 2

Re: CPU - Drapeaux - Obtenir leur état

Publié : lun. 24/oct./2016 15:45
par Mesa
Oui, on a accès aux FLAGS avec le deboggeur:

Code : Tout sélectionner

Procedure GetFlags()
  ! PushFD ; Copier les Flags sur la pile
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86 ; Si processeur 32 Bits ou OS 32 Bits alors utiliser EAX sinon utiliser RAX
    ! Pop EAX ; copier la pile dans eax ; x86
  CompilerElse 
    ! Pop RAX; copier la pile dans rax ; x64  
  CompilerEndIf
  ;Mettre un point d'arrêt ici avec F9 ou par le menu "Débogueur\Point d'arrêt"
  ProcedureReturn ; ProcedureReturn renvoie toujours eax ou rax
EndProcedure


ShowAssemblyViewer() ; Avec le point d'arrêt, la fenêtre qui s'ouvre montre bien que EAX ou RAX est égal à FLAGS
a.q=GetFlags()
Debug a
Debug Hex(a)
Debug Bin(a)

Le bit 21 des FLAGS permet de savoir si le CPU a le CPUID: code de Froggerprogger

Code : Tout sélectionner

;Reading out the CPUID-Data, if available
;
;by Froggerprogger 10.12.03 http://forum.purebasic.com/english/viewtopic.php?p=91098

Dim CpuFeatures.s (32,2)
CpuFeatures(0,0) = "FPU  :  available"
CpuFeatures(1,0) = "VME  :  Virtual 8086 Mode Enhancements"
CpuFeatures(2,0) = "DE  :  Debugging Extension, I/O Breakpoints"
CpuFeatures(3,0) = "PSE  :  Page Size Extension 4MB"
CpuFeatures(4,0) = "TSC  :  command RDTSC available"
CpuFeatures(5,0) = "MSR  :  commands RDMSR and WRMSR available"
CpuFeatures(6,0) = "PAE  :  Physical Address Extension > 32-Bit"
CpuFeatures(7,0) = "MCE  :  Machine Check Exception"
CpuFeatures(8,0) = "CX8  :  command CMPXCH8B available"
CpuFeatures(9,0) = "APIC  :  available"
CpuFeatures(10,0) = "<reserved>"
CpuFeatures(11,0) = "SEP  :  commands SYSENTER/SYSEXIT | SYSCALL/SYSRET available"
CpuFeatures(12,0) = "MTTR  :  supported"
CpuFeatures(13,0) = "PGE  :  supported"
CpuFeatures(14,0) = "MCA  :  available"
CpuFeatures(15,0) = "CMOV  :  commands CMOVxxx available, together with FPU, also FCOMI/FCMOV"
CpuFeatures(16,0) = "PAT"
CpuFeatures(17,0) = "PSE-36"
CpuFeatures(18,0) = "PSN  :  Processor serial number"
CpuFeatures(19,0) = "CLFSH  :  command CLFLUSH available"
CpuFeatures(20,0) = "<reserved>"
CpuFeatures(21,0) = "D5  :  Debug store supported"
CpuFeatures(22,0) = "ACPI  :  check temperature and control CPU"
CpuFeatures(23,0) = "MMX  :  supported"
CpuFeatures(24,0) = "FXSR  :  commands FXSAVE and FXRSTOR available "
CpuFeatures(25,0) = "SSE  :  supported"
CpuFeatures(26,0) = "SSE2  :  supported"
CpuFeatures(27,0) = "SS  :  SelfSnoop"
CpuFeatures(28,0) = "<reserved>"
CpuFeatures(29,0) = "TM  :  thermal monitor"
CpuFeatures(30,0) = "3DNow!  :  Instructions Extension available (AMD only)"
CpuFeatures(31,0) = "3DNow!  :  Insctructions available (AMD only)"


;test if EFlags Bit 21 can be changed. Then CPUID is available
!PUSHFD
!POP EAX
!MOV EBX, EAX
!XOR EAX, 00200000h
!PUSH EAX
!POPFD
!PUSHFD
!POP EAX
!XOR EAX, EBX
;jump to goon1, if CPUID is available
!JNZ goon1
MessageRequester("","No CPUID available.",0)
End

!goon1:
Global a.l, b.l, c.l, d.l

MessageRequester("Bouh","Chouette, vous avez un CPU plus récent qu'un Pentium III ! ;)) et voici ce qu'il a dans le ventre",#PB_MessageRequester_Info)

!MOV EAX, 0
!CPUID
!MOV [v_a], EAX
!MOV [v_b], EBX
!MOV [v_c], ECX
!MOV [v_d], EDX

b$=Left(PeekS(@b,-1,#PB_Ascii),4)
c$=Left(PeekS(@c,-1,#PB_Ascii),4)
d$=Left(PeekS(@d,-1,#PB_Ascii),4)

Debug a
Debug "Name:" + b$ + d$ + c$


If a >= 1
  !MOV EAX, 1
  !CPUID
  !MOV [v_a], EAX
  !MOV [v_b], EBX
  !MOV [v_c], ECX
  !MOV [v_d], EDX
  
  For i=0 To 31
    If d>>i&1   
      CpuFeatures(i,1) = "YES"
    Else
      CpuFeatures(i,1) = "NO"
    EndIf
  Next
  
Else
  For i=0 To 31
    CpuFeatures(i,1) = "no information available"
  Next
EndIf

For i=0 To 31
  Debug CpuFeatures(i,0) + " :     "+CpuFeatures(i,1)
Next
Mais si on veut afficher les FLAGS en détail, un allemand a fait ça:

Code : Tout sélectionner

;http://www.purebasic.fr/english/viewtopic.php?f=13&t=37083&hilit=PushF
; Define ShowAsmInfo

		OpenWindow(0,0,0,960,200,"ASM Information")
		Global AsmInfoID=TextGadget(0,0,0,960,500,"")
		Global AsmInfoText.s


		Macro WaitKey
				Repeat
				Until WaitWindowEvent(10)=#PB_Event_CloseWindow;#WM_CHAR
		EndMacro

		Macro ShowAsmInfo(Text)

				#DecimalMode=#True

				Global VarAX.l          ;der Ordnung halber alle Variablen deklarieren
				Global VarBX.l
				Global VarCX.l
				Global VarDX.l
				Global VarDI.l
				Global VarSI.l
				Global VarBP.l
				Global VarSP.l
				Global FA.b             ;C, P, A, Z, S, D, O - Flags
				Global FC.b
				Global FD.b
				Global FO.b
				Global FP.b
				Global FS.b
				Global FZ.b

				!PUSHFD                 ;Flags sichern
				!PUSHAD                 ;alle Register sichern
				!MOV [v_VarAX],eax      ;alle Register in Variablen schreiben
				!MOV [v_VarBX],ebx
				!MOV [v_VarCX],ecx
				!MOV [v_VarDX],edx
				!MOV [v_VarDI],edi
				!MOV [v_VarSI],esi
				!MOV [v_VarBP],ebp
				!MOV [v_VarSP],esp

				!PUSHFD                 ;das 32-bittige E-FLAG-Register auf den Stack schieben
				!POP eax                ;und in das EAX-Register laden

				!MOV [v_FC],0           ;für Carry-Flag; Variable erstmal auf Null
				!SHR eax,1              ;nach Rechts shiften, das letzte geshiftete Bit steht im Carry-Flag
				!ADC [v_FC],0           ;Wert des Carry-Flags zum Variablen-Wert addieren

				!MOV [v_FP],0           ;für Parity-Flag
				!SHR eax,2
				!ADC [v_FP],0

				!MOV [v_FA],0           ;für Auxiliary-Flag
				!SHR eax,2
				!ADC [v_FA],0

				!MOV [v_FZ],0           ;für Zero-Flag
				!SHR eax,2
				!ADC [v_FZ],0

				!MOV [v_FS],0           ;für Signum-Flag
				!SHR eax,1
				!ADC [v_FS],0

				!MOV [v_FD],0           ;für Direction-Flag
				!SHR eax,3
				!ADC [v_FD],0

				!MOV [v_FO],0           ;für Overflow-Flag
				!SHR eax,1
				!ADC [v_FO],0

				Delay(1)                ;sonst funktionierts direkt nach einem MessageRequester nicht

				;hWnd=GetForegroundWindow_()

				CompilerIf #DecimalMode
						AsmInfoText+"C="+Str(FC)+"  P="+Str(FP)+"  A="+Str(FA)+"  Z="+Str(FZ)+"  S="+Str(FS)+"  D="+Str(FD)+"  O="+Str(FO)+"   EAX="+Str(VarAX)+"  EBX="+Str(VarBX)+"  ECX="+Str(VarCX)+"  EDX="+Str(VarDX)+"  EDI="+Str(VarDI)+"  ESI="+Str(VarSI)+"  EBP="+Str(VarBP)+"  ESP="+Str(VarSP)+"     ["+Text+"]"+#CRLF$
				CompilerElse
						AsmInfoText+"C="+Str(FC)+"  P="+Str(FP)+"  A="+Str(FA)+"  Z="+Str(FZ)+"  S="+Str(FS)+"  D="+Str(FD)+"  O="+Str(FO)+"   EAX="+Hex(VarAX)+"  EBX="+Hex(VarBX)+"  ECX="+Hex(VarCX)+"  EDX="+Hex(VarDX)+"  EDI="+Hex(VarDI)+"  ESI="+Hex(VarSI)+"  EBP="+Hex(VarBP)+"  ESP="+Hex(VarSP)+"     ["+Text+"]"+#CRLF$
				CompilerEndIf
				SetWindowText_(AsmInfoID,@AsmInfoText)

				!POPAD                  ;die gesicherten Register wieder zurück holen
				!POPFD                  ;die gesicherten Flags wieder zurück holen

		EndMacro

; EndDefine

Global DxMul.l=1000
Global DxMem.l=123

Global x.l=50
Global y.l=100
Global Screenx.l=2000
Global Screeny.l=1000

EnableASM

MOV eax,x
MOV ecx,y
CMP eax,ScreenX      ; x > ScreenX ?
JG exitMP32
CMP ecx,ScreenY      ; y > SreenY ?
JG exitMP32
OR eax,ecx         ; x OR y < 0?
JS exitMP32

;MOV eax,DxMul      ; DxMul
;IMUL ecx            ; y*DxMul
IMUL ecx,DxMul      ; y*DxMul

;      SHL ecx,2            ; x*4
ShowAsmInfo("")
MOV eax,x            ; x
ShowAsmInfo("x")
SHL eax,2            ; x*4
ShowAsmInfo("x*4")
ADD eax,ecx         ; x*4+y*DxMul
ShowAsmInfo("x*4+y*dxmul")
ADD eax,DxMem         ; x*4+y*DxMul
ShowAsmInfo("+dxmem")
!exitMP32:

WaitKey
Mesa.

Re: CPU - Drapeaux - Obtenir leur état

Publié : lun. 24/oct./2016 16:25
par falsam
Merci Mesa
Le bit 21 des FLAGS permet de savoir si le CPU a le CPUID
La au moins on sait à quoi ça sert.

➽ CPUID : http://www.gladir.com/LEXIQUE/ASM/cpuid.htm

Si on souhaite lire le constructeur du processeur alors on met la valeur 0 dans le registre EAX pour lire ensuite les registre EBX, ECX, EDX (Sont fous ces fondeurs de mettre leurs noms sur 3 registres )

Code : Tout sélectionner

;CPUID  fournit  une interface pour demander des informations concernant un CPU.
;Cette instruction retourne les informations du microprocesseur dans les 4 registres suivants: EAX, EBX, ECX, EDX.

Procedure.s CPUGetVendor()
  Protected a.l ;Cette variable contiendra la valeur du registre EBX 
  Protected b.l ;Cette variable contiendra la valeur du registre EDX
  Protected c.l ;Cette variable contiendra la valeur du registre ECX   
  
  ;si EAX = 0 alors EAX retourne les valeurs des registres EBX, EDX, ECX
  !mov eax,0
  
  !cpuid 
  
  ;EBX ← chaîne de caractères d'identification du fabricant :
  ; Intel: 756E6547h ("Genu")
  ; AMD: 68747541h ("Auth")
  !mov [p.v_a], ebx
  
  ;EDX ← chaîne de caractères d'identification du fabricant :
  ; Intel: 49656E69h ("inel")
  ; AMD: 69746E65h ("enti")
  !mov [p.v_b], edx 
  
  ;ECX ← chaîne de caractères d'identification du fabricant :
  ; Intel: 6C65746Eh ("ntel")
  ; AMD: 444D4163h ("cAMD")
  !mov [p.v_c], ecx 
  
  Debug "Valeur du registre EBX: " + PeekS(@a, 4, #PB_Ascii)
  Debug "Valeur du registre EDX: " + PeekS(@b, 4, #PB_Ascii)
  Debug "Valeur du registre ECX: " + PeekS(@c, 4, #PB_Ascii)
  
  ProcedureReturn PeekS(@a, 4, #PB_Ascii) + PeekS(@b, 4, #PB_Ascii) + PeekS(@c, 4, #PB_Ascii)
EndProcedure

Debug "Fabricant: " + CPUGetVendor()

Re: CPU - Drapeaux - Obtenir leur état

Publié : lun. 24/oct./2016 17:42
par Ollivier
@Mesa

Merci pour contribution, j'ai rajouté une recommandation en tête de sujet.

Re: CPU - Drapeaux - Obtenir leur état

Publié : mar. 25/oct./2016 10:46
par Ar-S
(Sont fous ces fondeurs de mettre leurs noms sur 3 registres )
Mais c'est claire.

Re: CPU - Drapeaux - Obtenir leur état

Publié : mar. 25/oct./2016 19:40
par Ollivier
@Falsam

Merci pour ta contribution. L'inventaire des drapeaux d'états est arborescent. Par exemple, CpuId indique si l'instruction CMov est prise en charge ou non.

Re: CPU - Drapeaux - Obtenir leur état

Publié : sam. 29/oct./2016 11:31
par Kwai chang caine
Au bout de X codes, j'ai enfin à peu prés compris à quoi ça servait (Principalement celui de FALSAM :wink: )
C'est le bout du monde pour moi, mais ça reste passionnant 8O
Merci à tous 8)

Re: CPU - Drapeaux - Obtenir leur état

Publié : sam. 29/oct./2016 22:25
par Ollivier
Ben, c'est bien... Au moins, Falsam a su te donner un goût à ça, pendant le moment où je ne peux être sur un ordinateur!

Scully me rappelle des trucs algébriques : j'espère que tu m'en excuseras pour le retard occasionné!