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.