ZitatAuf der Seite, auf der ich das Skript einsetzten will, klappt das nicht
Und warum postest du uns dann ein Script, das funktioniert?
Hälst du uns für blöd?
ZitatAuf der Seite, auf der ich das Skript einsetzten will, klappt das nicht
Und warum postest du uns dann ein Script, das funktioniert?
Hälst du uns für blöd?
ExBerliner, damit findest du aber m.E. nur die zum Dateityp gehörende ausführende Datei. Ich kann doch HTML standardmäßig mit Scite öffnen und trotzdem Opera als StandardBrowser haben
i2C, dein wunsch ist mir Befehl, habe folgendes aus einem meiner Scripte rauskopiert...
Das Script habe ich übrigens täglich mehrfach im Einsatz, "googlen" tu ich schon lange nicht mehr "von Hand"^^
#include <File.au3>
#include <Array.au3>
$browserinfo=__GetBrowserInfo()
_arraydisplay($browserinfo)
Func __FindPathToDefaultBrowser() ;findet den vollen Pfad zum Standardbrowser
Local $RegLocation = RegRead("HKEY_CLASSES_ROOT\" & ".html", "")
Local $RegLoc = RegRead("HKEY_CLASSES_ROOT\" & $RegLocation & "\Shell\Open\command", "")
$RegLoc = StringMid($RegLoc, 2, StringInStr($RegLoc, '"', 0, 2) - 2)
If $RegLoc = "" Then
MsgBox(262144, "Fehler!", "Der Pfad zum in Windows installierten Standardbrowser konnte nicht ermittelt werden!" & @CRLF & "Bitte installieren sie einen Browser oder teilen Sie dem System den Standardbrowser mit." & @CRLF & "Das Programm wird beendet!")
Return SetError(-1,0,0)
;_GUIClose()
Else
Return SetError(@error, 0, $RegLoc)
EndIf
EndFunc ;==>FindPathToDefaultBrowser
Func __GetBrowserInfo() ;holt sich aus der registry den standardbrowser und setzt die Fensternamen
Local $cPath, $cFDrive, $cFDir, $cFName, $cFExt
Local $browsernewwindow,$Browsername,$Browserprocess
local $DefaultBrowser = __FindPathToDefaultBrowser()
if @error then return seterror(-1,0,0)
Local $a = _PathSplit($DefaultBrowser, $cFDrive, $cFDir, $cFName, $cFExt)
;_arraydisplay($a)
local $browser_exe = $a[3] & $a[4]
local $Browser = $a[3]
Switch $Browser
Case "OPERA"
$Browsername = "Opera"
$Browserprocess = "Opera.exe"
$browsernewwindow = "Schnellwahl - " & $Browsername
Case "IEXPLORER"
$Browsername = "Windows Internet Explorer"
$Browserprocess = "iexplore.exe"
$browsernewwindow = "Neue Registerkarte - " & $Browsername
Case "Firefox"
$Browsername = "Mozilla Firefox"
$Browserprocess = "firefox.exe"
$browsernewwindow = $Browsername
Case "IRON"
$Browsername = "Iron"
$Browserprocess = "iron.exe"
$browsernewwindow = "Neuer Tab - " & $Browsername
Case Else
$Browsername = "Unbekannter Browser"
$Browserprocess = ""
$browsernewwindow = ""
EndSwitch
Dim $ret[3]
$ret[0]=$Browsername
$ret[1]=$Browserprocess
$ret[2]=$browsernewwindow
return $ret
EndFunc ;==>_GetBrowserInfo
AAAAlso, in urseligen DOS-Zeiten bestand das Betriebssystem nur aus einer Handvoll Dateien.
Das was heutzutage über die WINAPI und Dll´s abgewickelt wird, hat man früher mit den sogenannten Interrupts gemacht. Das war nichts weiter als ein Funktionsaufruf (Interrupt, weil man definiert laufende Programme unterbrechen konnte) welcher alle möglichen Dinge ausführen konnte. Eine der "berühmtesten" ist der INT21h, der sich mit der gesamten Ein- und Ausgabe von Daten (also auch Dateien) befasst. DIESE SEITE sollte genügend informationen liefern^^
Im AX-Register wird dabei die Funktion(snummer) übergeben, bei INT21h ist AX=09h für "Daten ausgeben" zuständig. In den anderen Registern werden die Eingabeparameter eingetragen und die Register enthalten nach dem "Interrupt" dann die entsprechenden von der Funktion zurückgegebenen Daten. Daher ist es IMMENS wichtig, sorgfältig die entsprechenden Register zu beschreiben, ansonsten kann das ganz schön in die Hose gehen! Die "Mausschubser" von heute würden nicht schlecht gucken, wenn nach einem "verunglückten" INT21 mit falschen Eingabedaten plötzlich die Festplatte nicht mehr richtig lesbar wäre...oder Dateien fehlen oder alles voller Dateien ist die keiner haben wollte^^.
Den Schnickschnack mit Fensterchen und "Wollen Sie bestimmt die FAT überschreiben bzw die Festplatte formatieren? Ja Nein WeisNicht" gibts erst seit Windows...
Also aufpassen!
Und manch einer hat schon gekotzt, nur weil er das "h" (hexadezimal) hinter einer Ziffer vergessen hatte und so statt Daten zu lesen, Datei(en) löschen ausführte 60<>60h
, aber das lernt man dann SEHR schnell^^
ZitatDafür fehlt jetzt aber die Rotation
Die hat schon immer gefehlt, siehe unverändertes JS-Programm, ich hatte mich die ganze Zeit gefragt, wieso dort nirgendwo die Funktion rotation() aufgerufen wird! /EDIT/ Aaaah, das waren die auskommentierten 2 Zeilen^^ ![]()
Hab mir jetzt mal das Orginal downgeloaded, na gut, bissl Rotation, das macht den Kohl nicht fett, da der FPATAN()-Befehl immer noch die Hälfte der Performance schluckt (bis zu 300 Takte! )
Um das zu umgehen, müsste man entweder eine "schnelle" Bibliothek einbinden, oder selbst eine Ergebnisliste für FPATAN() erstellen (so wie"früher" im Tabellenbuch für Sinus und Cosinus). Das ist mir zu aufwendig^^
@sprenger, wg deinem comfile....guck mal nach, was der INT 20 macht nach dem 1. INT21 ![]()
#include "FASM.au3"
#include <Array.au3>
$Fasm = FasmInit()
FasmReset($Fasm)
Fa("use32")
Fa("org " & FasmGetBasePtr($Fasm)) ;<-----------startadresse des Programms im speicher ,Basisadresse
fa("mov ebx,1")
fa("mov [array+ebx*4],2") ;array ist nur der "Abstand" bis zur Basisadresse, also hier ca. 30
fa("mov eax,[array+ebx*4]") ;der assembler macht aus array ---> Basisadresse+30
[/autoit] [autoit][/autoit] [autoit]fa("ret ")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]fa("array dd 1 dup(3)") ; hier ist das 30. Byte im Programm, also ist array=30
[/autoit] [autoit][/autoit] [autoit]ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
$a = MemoryFuncCall("int", FasmGetFuncPtr($Fasm))
_ArrayDisplay($a)
Func fa($str) ; Nur für die bequemlichkeit ![]()
FasmAdd($Fasm, $str)
EndFunc ;==>fa
FasmExit($Fasm)
[/autoit]Hi, habs gerade gemerkt, der Handle hbmp der _CreateNewBitmap32() ist offensichtlich nicht zu benutzen, ich weiss, dass ich die Funktion ziemlich gekürzt hatte, scheinbar war einiges, was ich rausgeschmissen hatte, doch nicht so überflüssig^^
Bis auf weiters kann man mit GDI+-DRAW-Befehlen so auf die mit _CreateNewBitmap32() erzeugten Bitmaps zugreifen:
local $hbmp_buffer,$ptr_buffer
$hdc_buffer=_CreateNewBmp32($w, $h,$ptr_buffer, $hbmp_buffer)
$hGraphic_w = _GDIPlus_GraphicsCreateFromHDC($hdc_buffer)
_GDIPlus_GraphicsDrawline($hGraphic_w, 10, 10,400,200,$hpen)
Optimierung von Code am Beispiel des Tunnelfluges
Wer das Beispiel im vorherigen Post durchgegangen ist, der hat wahrscheinlich den Kopf geschüttelt ob so viel Unfähigkeit des Programmierers^^
Warum?
Nun, wir (ich) haben ein AutoItScript nach Assembler portiert, aber dieses gemacht, OHNE NACHZUDENKEN!
Allein das AutoItScript hat reichlich Kürzungs- und Optimierungsbedarf!
Selbst mit geringen mathematischen Kenntnissen, kommt man auf folgendes Script:
;Idea taken from http://js1k.com/demo/462
;Ported to AutoIt by UEZ Build 2010-08-20
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#AutoIt3Wrapper_Run_After=del /f /q "Star Burst_Obfuscated.au3"
#AutoIt3Wrapper_Run_After=upx.exe --ultra-brute "%out%"
;~ #AutoIt3Wrapper_Run_After=upx.exe --best "%out%"
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
;Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local $H = 332, $W = 332
; Initialize GDI+
_GDIPlus_Startup()
$hGUI = GUICreate("GDI+ Test", $W, $H)
GUISetState()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($W, $H, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
; Using antialiasing
;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 0)
; Create a Brush object
Local $hBrush = _GDIPlus_BrushCreateSolid()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
[/autoit] [autoit][/autoit] [autoit]adlibregister("_fps",1000)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]global $pi = ACos(-1), $pi2 = 2 * $pi, $pi05 = ACos(-1) * 0.5, $fps
Local $HW = $H * 0.5, $HH = $W * 0.5
Local $A0 = 0, $A1 = 0, $A2 = 0, $A3 = 0
Local $ox = 0, $oy = 0, $0z = 0
Local $tu = 0, $tv = 0
Local $speed = 2
Local $i, $j, $x, $y, $o
Local $cc, $ss, $z, $col
Local $dx, $dy, $dz, $rd, $A, $B, $C, $R, $t1, $tu, $tv, $q, $g, $l
Local $d[$W + 1]
$zwonulldrei=203.718330632686
$nulldrei=0.390625
;$a1=0.07
While 1;Sleep(10)
_GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000)
For $i = 0 To $H Step $speed
For $j = 0 To $W Step $speed
$dx=($j/$W)-0.5;
$dy=($i/$H)-0.5;
$tu=int($zwonulldrei*ATan2($dy,$dx))
$tv=($nulldrei/sqrt($dx*$dx+$dy*$dy))+$A1
$tv=int($tv*256)
$g = Hex(bitand(Bitxor($tu , $tv), 0xFF), 2)
$col = "0xFF" & $g & $g & $g
_GDIPlus_BrushSetSolidColor($hBrush, $col)
_GDIPlus_GraphicsFillRect($hBackbuffer, $j, $i, $speed, $speed, $hBrush)
Next
Next
$A1 += 0.07
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $W, $H)
$fps+=1
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $A1 = ' & $A1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
WEnd
func _FPS()
winsettitle($hgui,"",$FPS)
$FPS=0
endfunc
Func Rotate($t)
$cc = Cos($t)
$ss = Sin($t)
$z = $x * $cc - $y * $ss
$y = $x * $ss + $y * $cc
$x = $z
EndFunc
func atan2($y,$x)
return (2*atan($y/($x+sqrt($x*$x+$y*$y))))
endfunc
Func ATan2_UEZ($y,$x)
Switch $x
Case ($x > 0)
Return ATan($y / $x)
Case ($x < 0 And $y >= 0)
Return ATan($y / $x + $pi)
Case ($x < 0 And $y < 0)
Return ATan($y / $x - $pi)
Case ($x = 0 And $y > 0)
Return $pi05
Case ($x = 0 And $y < 0)
Return -$pi05
Case ($x = 0 And $y = 0)
Return 0
EndSwitch
EndFunc
Func _Exit()
; Clean up
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hBackbuffer)
_GDIPlus_GraphicsDispose($hGraphics)
; Uninitialize GDI+
_GDIPlus_Shutdown()
Exit
EndFunc
Das sieht schon anders aus!
Viele Variablen sind verschwunden und jede Menge Rechnerei auch!
Da wir nun nicht mehr so viele Variablen haben, optimieren wir unseren Assemblercode so, daß wir die Variablen auf dem Stack des Coprozessors lagern.
Anstatt langsam auf SPEICHER zuzugreifen, holen wir die Variablen aus dem schnellen Register-STACK des Prozessors.
Ein FMUL ST0,ST4 ist wesentlich schneller als ein FMUL [Speicherstelle]!
Leider passen nicht alle Variablen auf den Stack, so daß wir immer noch ein wenig Speed verschenken, aber durch die ERSTE Optimierung haben wir die Geschwindigkeit des Programms nahezu verdoppelt!
#include <FASM.au3>
#include <MemoryDll.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <GDIConstants.au3>
#include <array.au3>
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]$b=520
$h=520
global $Fasm = FasmInit(), $FPS
_createbytecode() ;assemblercode erstellen
;backbuffer erstellen für die Bitmap
local $ptr_bitmap,$hbmp_bitmap ;byref
$hDC_bitmap=_CreateNewBmp32($b, $h, $ptr_bitmap,$hbmp_bitmap) ;DC, Pointer auf die Bitmapdaten und ein Handle für GDI+....eine eierlegende Wollmilchsau
$hgui=guicreate("",$b,$h,1,1)
$hdc_gui=_WinAPI_GetDC($hgui)
guisetstate()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
adlibregister("_fps",1000) ;FramesPerSecond
$step=0.07 ;das ist die Schrittweite, um die der Tunnelflug ein Frame weiter gezeichnet wird
[/autoit] [autoit][/autoit] [autoit]$struct_a=dllstructcreate("float") ;
dllstructsetdata($struct_a,1,$step) ;zähler, wird nach jedem Frame um $step erhöht
while 1;sleep(20)
$Ret = MemoryFuncCall("int", FasmGetFuncPtr($Fasm), "int", $b,"int",$h,"float",dllstructgetdata($struct_a,1),"ptr", $ptr_bitmap)
_winapi_bitblt($hdc_gui,0,0,$b,$h,$hDC_bitmap,0,0,$srccopy) ;bitmap in die GUI blitten
$fps+=1
dllstructsetdata($struct_a,1,dllstructgetdata($struct_a,1)+$step) ;zähler erhöhen
wend
func _fps()
winsettitle($hgui,"",$fps)
$fps=0
endfunc
Func _Exit()
Exit
EndFunc
func _createbytecode()
[/autoit] [autoit][/autoit] [autoit]FasmReset($Fasm)
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "use32")
FasmAdd($Fasm, "org " & FasmGetBasePtr($Fasm))
FasmAdd($Fasm, "mov eax,[esp+4]") ;breite
FasmAdd($Fasm, "mov [breite],eax") ;
FasmAdd($Fasm, "mov eax,[esp+8]") ;hoehe
FasmAdd($Fasm, "mov [hoehe],eax") ;
FasmAdd($Fasm, "mov eax,[esp+12]") ;A1
FasmAdd($Fasm, "mov [va1],eax") ;
FasmAdd($Fasm, "mov edi,[esp+16]") ;Ptr auf bitmapdaten
;FasmAdd($Fasm, "mov [bitmap],eax") ;
FasmAdd($Fasm, "FINIT") ;copro init
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "mov dword[vi],0") ;schleifenzähler
FasmAdd($Fasm, "mov dword[vj],0") ;
;stack mit konstanten laden, diese bleiben während des gesamten durchlaufs im stack!
FasmAdd($Fasm, "fld1") ;st0=1
FasmAdd($Fasm, "fidiv [hoehe] ") ;st0=1/h
FasmAdd($Fasm, "fld [minuseinhalb]") ;st0=-0.5
FasmAdd($Fasm, "fld [zwonulldrei]") ;st0=203.xx st1=-0.5
FasmAdd($Fasm, "fld [nulldrei]") ;st0=0.39 st1=203.xx st2=-0.5 st3=1/h
;leider hat die inverse breite keinen platz mehr auf dem stack gefunden und muss in speicher gelagert werden
FasmAdd($Fasm, "fld1") ;st0=1 st1=breite
FasmAdd($Fasm, "fidiv [breite]") ;st0=1/b
FasmAdd($Fasm, "fstp [invbreite]") ;st0=0.39 st1=203.xx st2=-0.5 st3=1/h 21
;schleifen
FasmAdd($Fasm, "mov edx,[hoehe]") ;
FasmAdd($Fasm, "i_schleife:") ; for i=0 to h
FasmAdd($Fasm, "mov ecx,[breite]") ; schleifenzähler breite
FasmAdd($Fasm, "j_schleife:") ; for j=0 to w
;~ ;$dx=($j-$HW)/$W;
FasmAdd($Fasm, "fild dword[vj]") ;st0=j st1=0.39 st2=203.xx st3=-0.5 st4=1/h
FasmAdd($Fasm, "fmul [invbreite] ") ;st(0)=j/w
FasmAdd($Fasm, "fadd st0,st3") ;st(0)=j/w-0.5 st1=0.39 st2=203.xx st3=-0.5 st4=1/h
;$dy=($i-$HH)/$H
FasmAdd($Fasm, "fild [vi]") ;st0=i st1=dx st2=0.39 st3=203.xx st4=-0.5 st5=1/h
FasmAdd($Fasm, "fmul st0,st5") ;st(0)=i/h
FasmAdd($Fasm, "fadd st0,st4") ;st(0)=i/h-0.5=dy st1=dx st2=0.39 st3=203.xx st4=-0.5 st5=1/h
;$tu=int($5div2pi*ATan2($dy,$dx))
FasmAdd($Fasm, "fld st0") ;st0=dy st1=dy st2=dx
FasmAdd($Fasm, "fld st2") ;st0=dx st1=dy st2=dy st3=dx st4=0.39 st5=203.xx st6=-0.5 st7=1/h
;weil atan2 2 stackplätze "verbraucht" bzw zerstört, konnte 1/b nicht auf den stack!
FasmAdd($Fasm, "fpatan") ;st0=atan2 st1=dy st2=dx st3=0.39 st4=203.xx st5=-0.5 st6=1/h
FasmAdd($Fasm, "fmul st0,st4") ;st0=atan2*203
FasmAdd($Fasm, "fistp [vtu]") ;st0=dy st1=dx st2=0.39 st3=203.xx st4=-0.5 st5=1/h
;$tv=($nulldrei/sqrt($dx*$dx+$dy*$dy))+$a1
FasmAdd($Fasm, "fmul st0,st0") ;st0=dy^2 st1=dx st2=0.39 st3=203.xx st4=-0.5 st5=1/h
FasmAdd($Fasm, "fxch") ;st0=dx st1=dy^2 st2=0.39 st3=203.xx st4=-0.5 st5=1/h
FasmAdd($Fasm, "fmul st0,st0") ;st0=dx^2 st1=dy^2 st2=0.39 st3=203.xx st4=-0.5 st5=1/h
FasmAdd($Fasm, "faddp ") ;st0=dy^2+dx^2 st1=0.39 st2=203.xx st3=-0.5 st4=1/h
FasmAdd($Fasm, "fsqrt") ;st0=sqrt(dy^2+dx^2) st1=0.39 st2=203.xx st3=-0.5 st4=1/h
FasmAdd($Fasm, "fdivr st0,st1 ");st0=0.3/sqrt st1=0.39 st2=203.xx st3=-0.5 st4=1/h
FasmAdd($Fasm, "fadd [va1]") ;st0=0.3/sqrt+a1 st1=0.39 st2=203.xx st3=-0.5 st4=1/h
FasmAdd($Fasm, "fimul [v256]") ;st0=(0.3/sqrt+a1)*256 st1=0.39 st2=203.xx st3=-0.5 st4=1/h
FasmAdd($Fasm, "fistp [vtv]") ;st0=0.39 st1=203.xx st2=-0.5 st3=1/h
;stack ist in dem zustand, wie er am anfang der schleife war
[/autoit] [autoit][/autoit] [autoit];XOR
FasmAdd($Fasm, "mov eax,[vtv]") ;
FasmAdd($Fasm, "xor eax,[vtu]") ;
FasmAdd($Fasm, "and eax,0xFF") ;farbe von RR, GG und BB
;pixelfarbe (grauton) erstellen
FasmAdd($Fasm, "mov ebx,0xFF") ;alpha AA
FasmAdd($Fasm, "shl ebx,8") ;AA00
FasmAdd($Fasm, "or ebx,eax") ;AABB
FasmAdd($Fasm, "shl ebx,8") ;AABB00
FasmAdd($Fasm, "or ebx,eax") ;AABBGG
FasmAdd($Fasm, "shl ebx,8") ;AABBGG00
FasmAdd($Fasm, "or eax,ebx") ;AABBGGRR
FasmAdd($Fasm, "stosd") ;mov [edi],eax pixel in die bitmap schreiben
FasmAdd($Fasm, "dec ecx" ) ;schleifenzähler breite
FasmAdd($Fasm, "mov [vj],ecx" ) ;schleifenzähler breite
FasmAdd($Fasm, "jnz j_schleife") ;so lange bis 0
FasmAdd($Fasm, "dec edx") ;schleifenzähler hoehe
FasmAdd($Fasm, "mov [vi],edx" ) ;schleifenzähler breite
FasmAdd($Fasm, "jnz i_schleife") ;so lange bis 0
FasmAdd($Fasm, "ret 16");Programmende
[/autoit] [autoit][/autoit] [autoit];variablen, einige werden nicht gebraucht, habe aber versucht, das AutoItscript zu übernehmen
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "nulldrei dd 0.390625") ;100/256
FasmAdd($Fasm, "zwonulldrei dd 203.718330632686")
FasmAdd($Fasm, "minuseinhalb dd -0.5")
FasmAdd($Fasm, "v256 dd 256")
FasmAdd($Fasm, "hoehe dd 0")
FasmAdd($Fasm, "breite dd 0")
FasmAdd($Fasm, "invbreite dd 0.0")
FasmAdd($Fasm, "va1 dd 0.0")
FasmAdd($Fasm, "vtu dd 0")
FasmAdd($Fasm, "vtv dd 0")
FasmAdd($Fasm, "vi dd 0")
FasmAdd($Fasm, "vj dd 0")
$Binary = FasmGetBinary($Fasm) ;syntaxerror im Assembler abfangen abfangen
;~ If @Extended Then ;syntax-error aufgetreten
;~ $Error = FasmGetLastError()
;~ ConsoleWrite("Error Code:" & $Error[0] & @CRLF & "Error Message:" & $Error[1] & @CRLF & "Error Line:" & $Error[2] & @CRLF)
;~ Else ;syntax ok
ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
filedelete("test.bin") ;assembly für externen debugger
filewrite("test.bin",binarytostring(String(FasmGetBinary($Fasm))))
endfunc
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe DC und ptr und handle auf die Bitmapdaten
;by Andy
Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
Local $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
DllStructSetData($tBMI, "Width", $iwidth)
DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
DllStructSetData($tBMI, "Planes", 1)
DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', $DIB_RGB_COLORS, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
$ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
;_arraydisplay($adib)
_WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
Return $hcdc ;DC der Bitmap zurückgeben
EndFunc ;==>_CreateNewBmp32
Schau dir mal in der Hilfe die Datumsbefehle an ( *DATE* im Reiter "Suchen" eingeben, die Sternchen nicht vergessen!)
Von den vielen Befehlen ist für dich besonders
_NowDate() und _NowCalcDate()
[/autoit]interessant...
Beispiel Verwendung von Floatingpoint-Registern und ein Versuch, ein AutoIt-Script 1:1 in Assembler umzusetzen
Für Berechnungen mit Fließkommazahlen (bis zu 80 Bit Genauigkeit) verwende ich den "Coprozessor" mit seinem eigenen Registerstack (ST0 bis ST7)
alle Coprozessorbefehle fangen mit F an, also FADD, FMUL, FDIV usw.
Zunächst muss der Copro mit FINIT initialisiert werden.
Die Coprozessorbefehle arbeiten (fast) alle mit dem internen Stack. Um nun 2 Zahlen zu multiplizieren, lädt man beide Zahlen per FLD auf den Stack und multipliziert dann:
FINIT
FLD dword[float1] ;ST0=float1
FLD [float2] ;ST0=float2 ST1=float1 ;wenn der Befehl anhand des Namens den Typ feststellen kann, braucht man den Typ nicht anzugeben
FMUL st0,st1 ;ST0=float2+float1 ST1=float1
;dritte Zahl addieren, intgr ist aber ein Integer, macht nix, man kann auch Integer (erlkennt man an dem I im Namen des Befehls) laden
FIADD [float3] ;sogar direkt auf die Speicherstelle zugreifen ist möglich ST0=intgr+float2+float1 ST1=float1
FST [float1] ;Inhalt von ST0 wird an die Speicherstelle [föoat1] geschrieben ST0=intgr+float2+float1 ST1=float1
FSTP [float1] ;Inhalt von ST0 wird an die Speicherstelle [föoat1] geschrieben, und dann st0 vom Stack gepopt danach ist ST0=float1
float1 dd 0.004 ;Fliesskommazahlen immer mit Komma!
float2 dd 58.0 ;Fliesskommazahlen immer mit Komma!
intgr dd 66 ;Das ist ein INT! 66.0 wäre float
Alles anzeigen
ACHTUNG! Ab jetzt wird ST0 in EAX zurückgegeben, um also schnell mal das aktuelle Register auf dem Coprozessorstack (ST0) im Programm zu checken, einfach ein RET hinter den entsprechenden Befehl setzen, dabei im Dll-Call den Rückgabetyp entweder auf float oder double setzen.
Das Programm "Tunnelflug" habe ich freundlicherweise von UEZ bekommen, der es wiederum von einem JavaScript abgekupfert hat^^
AutoIt-Version: (jaja, sieht wüst aus, aber so habe ich es bekommen^^)
;Idea taken from http://js1k.com/demo/462
;Ported to AutoIt by UEZ Build 2010-08-20
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#AutoIt3Wrapper_Run_After=del /f /q "Star Burst_Obfuscated.au3"
#AutoIt3Wrapper_Run_After=upx.exe --ultra-brute "%out%"
;~ #AutoIt3Wrapper_Run_After=upx.exe --best "%out%"
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
;Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local $H = 132, $W = 132
; Initialize GDI+
_GDIPlus_Startup()
$hGUI = GUICreate("GDI+ Test", $W, $H)
GUISetState()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($W, $H, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
; Using antialiasing
;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 0)
; Create a Brush object
Local $hBrush = _GDIPlus_BrushCreateSolid()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
[/autoit] [autoit][/autoit] [autoit]adlibregister("_fps",1000)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]global $pi = ACos(-1), $pi2 = 2 * $pi, $pi05 = ACos(-1) * 0.5, $fps
Local $HW = $H * 0.5, $HH = $W * 0.5
Local $A0 = 0, $A1 = 0, $A2 = 0, $A3 = 0
Local $ox = 0, $oy = 0, $0z = 0
Local $tu = 0, $tv = 0
Local $speed = 2
Local $i, $j, $x, $y, $o
Local $cc, $ss, $z, $col
Local $dx, $dy, $dz, $rd, $A, $B, $C, $R, $t1, $tu, $tv, $q, $g, $l
Local $d[$W + 1]
While 1;Sleep(10)
_GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000)
$o = 0
For $i = 0 To $H Step $speed
For $j = 0 To $W Step $speed
$dx=($j-$HW)/$W;
$dy=($i-$HH)/$H;
$dz=-1;
$l=Sqrt($dx*$dx+$dy*$dy+$dz*$dz);
$dx/=$l;
$dy/=$l;
$dz/=$l;
$X=$dx;
$Y=$dy;
;//rotate(A0-A2);
$dy=$Y;
$Y=$dz;
$dx=$X;
$X=$dy;
;//rotate(A3);
$dy=$X;
$dz=$Y;
$R=100;
$A=$dx*$dx+$dy*$dy;
$B=2*($dx*$ox+$dy*$oy);
$C=$ox*$ox+$oy*$oy-$R*$R;
$rd=Sqrt($B*$B-4*$A*$C);
$q=-.5*($B-$rd);
$t1=$C/$q;
$tu=5*ATan2($dy,$dx)/$Pi2;
$tv=$dz*$t1/256;
$tv+=$A1;
$g = Hex(bitand(Bitxor(int($tu * 256), int($tv * 256)), 0xFF), 2)
$col = "0xFF" & $g & $g & $g
_GDIPlus_BrushSetSolidColor($hBrush, $col)
_GDIPlus_GraphicsFillRect($hBackbuffer, $j, $i, $speed, $speed, $hBrush)
; $o += 1
Next
; $A0 += 0.015
;~ $A2 += 0.041
;~ $A3 += 0.009
Next
$A1 += 0.07
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $W, $H)
$fps+=1
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $A1 = ' & $A1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
WEnd
func _FPS()
winsettitle($hgui,"",$FPS)
$FPS=0
endfunc
Func Rotate($t)
$cc = Cos($t)
$ss = Sin($t)
$z = $x * $cc - $y * $ss
$y = $x * $ss + $y * $cc
$x = $z
EndFunc
func atan2($y,$x)
return (2*atan($y/($x+sqrt($x*$x+$y*$y))))
endfunc
Func ATan2_UEZ($y,$x)
Switch $x
Case ($x > 0)
Return ATan($y / $x)
Case ($x < 0 And $y >= 0)
Return ATan($y / $x + $pi)
Case ($x < 0 And $y < 0)
Return ATan($y / $x - $pi)
Case ($x = 0 And $y > 0)
Return $pi05
Case ($x = 0 And $y < 0)
Return -$pi05
Case ($x = 0 And $y = 0)
Return 0
EndSwitch
EndFunc
Func _Exit()
; Clean up
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hBackbuffer)
_GDIPlus_GraphicsDispose($hGraphics)
; Uninitialize GDI+
_GDIPlus_Shutdown()
Exit
EndFunc
Umsetzung in Assembler, ich habe versucht, die Rechenschritte im AutoIt-Programm direkt in Assemblerbefehle umzusetzen^^
Die eigentliche Stärke des Coprozessors, OHNE Zugreifen auf Prozessorregister (EAX, EBX usw) und Speicher, sondern nur mit den eigenen 8 ST-Registern zu arbeiten (parallel zum Prozessor! ) habe ich hier NICHT ausgespielt!
Im Apfelmännchen habe ich das wesentlich besser gelöst, aber das war mir dann für ein TUT doch etwas heavy^^
Weiterhin werden extrem viele Speicherschreib- und Lesebefehle durchgeführt. Da die Cachelines jedes mal mit "falschen" Daten gefüllt sind, ist das ein sehr schönes Beispiel, wie man auch mit Assembler SEHR langsame Programme erstellen kann! aber es ist wesentlich schneller als das AutoIt-Script^^ (wobei mein Opera mit dem compilierten Javacode fast ähnlich schnell ist! )
#include <FASM.au3>
#include <MemoryDll.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <GDIConstants.au3>
#include <array.au3>
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]$b=520
$h=520
global $Fasm = FasmInit(), $FPS
_createbytecode() ;assemblercode erstellen
;backbuffer erstellen für die Bitmap
local $ptr_bitmap,$hbmp_bitmap ;byref
$hDC_bitmap=_CreateNewBmp32($b, $h, $ptr_bitmap,$hbmp_bitmap) ;DC, Pointer auf die Bitmapdaten und ein Handle für GDI+....eine eierlegende Wollmilchsau
$hgui=guicreate("",$b,$h,1,1)
$hdc_gui=_WinAPI_GetDC($hgui)
guisetstate()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
adlibregister("_fps",1000) ;FramesPerSecond
$step=0.07 ;das ist die Schrittweite, um die der Tunnelflug ein Frame weiter gezeichnet wird
[/autoit] [autoit][/autoit] [autoit]$struct_a=dllstructcreate("float") ;
dllstructsetdata($struct_a,1,$step) ;zähler, wird nach jedem Frame um $step erhöht
while 1;sleep(20)
$Ret = MemoryFuncCall("int", FasmGetFuncPtr($Fasm), "int", $b,"int",$h,"float",dllstructgetdata($struct_a,1),"ptr", $ptr_bitmap)
_winapi_bitblt($hdc_gui,0,0,$b,$h,$hDC_bitmap,0,0,$srccopy) ;bitmap in die GUI blitten
$fps+=1
dllstructsetdata($struct_a,1,dllstructgetdata($struct_a,1)+$step) ;zähler erhöhen
wend
func _fps()
winsettitle($hgui,"",$fps)
$fps=0
endfunc
Func _Exit()
Exit
EndFunc
func _createbytecode()
[/autoit] [autoit][/autoit] [autoit]FasmReset($Fasm)
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "use32")
FasmAdd($Fasm, "org " & FasmGetBasePtr($Fasm))
FasmAdd($Fasm, "mov eax,[esp+4]") ;breite
FasmAdd($Fasm, "mov [breite],eax") ;
FasmAdd($Fasm, "mov eax,[esp+8]") ;hoehe
FasmAdd($Fasm, "mov [hoehe],eax") ;
FasmAdd($Fasm, "mov eax,[esp+12]") ;A1
FasmAdd($Fasm, "mov [va1],eax") ;
FasmAdd($Fasm, "mov edi,[esp+16]") ;Ptr auf bitmapdaten
;FasmAdd($Fasm, "mov [bitmap],eax") ;
FasmAdd($Fasm, "FINIT") ;copro init
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "mov dword[vo],0") ; init
FasmAdd($Fasm, "mov dword[vi],0") ;schleifenzähler
FasmAdd($Fasm, "mov dword[vj],0") ;
FasmAdd($Fasm, "mov eax,dword[breite]") ;HW=BREITE/2
FasmAdd($Fasm, "shr eax,1") ;
FasmAdd($Fasm, "mov [vhw],eax") ;
FasmAdd($Fasm, "mov eax,dword[hoehe]") ;HH=HOEHE/2
FasmAdd($Fasm, "shr eax,1") ;
FasmAdd($Fasm, "mov [vhh],eax") ;
;schleifen
FasmAdd($Fasm, "mov edx,[hoehe]") ;
FasmAdd($Fasm, "i_schleife:") ; for i=0 to h
FasmAdd($Fasm, "mov ecx,[breite]") ; schleifenzähler breite
FasmAdd($Fasm, "j_schleife:") ; for j=0 to w
;~ ;$dx=($j-$HW)/$W;
FasmAdd($Fasm, "fild dword[vj]") ;st(0)=j
FasmAdd($Fasm, "fisub dword[vhw]") ;st(0)=j-hw
FasmAdd($Fasm, "fidiv dword[breite]");st(0)=(j-hw)/w
FasmAdd($Fasm, "fst dword[vdx]") ;dx speichern
FasmAdd($Fasm, "fmul st0,st0") ;st(0)=dx^2 ;26
;$dy=($i-$HH)/$H
FasmAdd($Fasm, "fild [vi]") ;st(0)=i
FasmAdd($Fasm, "fisub [vhh]") ;st(0)=i-hh
FasmAdd($Fasm, "fidiv [hoehe]") ;st(0)=(j-hw)/h
FasmAdd($Fasm, "fst dword[vdy]") ;dy speichern
;dz=-1
FasmAdd($Fasm, "mov [vdz],-1") ;dz=-1
;$l=Sqrt($dx*$dx+$dy*$dy+$dz*$dz);
FasmAdd($Fasm, "fmul st0,st0") ;st(0)=dy^2 st(1)= dx^2
FasmAdd($Fasm, "fadd st0,st1") ;st(0) =dx^2+dy^2
FasmAdd($Fasm, "fld1") ;st(0) =1
FasmAdd($Fasm, "fadd st0,st1") ;st(0) =dx^2+dy^2+1
FasmAdd($Fasm, "fsqrt") ;st(0)= sqrt(dx^2+dy^2+1)
;dx=dx/l
FasmAdd($Fasm, "fld [vdx]") ;st0=dx st1=l
FasmAdd($Fasm, "fdiv st0,st1") ;st0=dx/l
FasmAdd($Fasm, "fstp dword[vdx]") ;dx=dx/l
;dy=dy/l
FasmAdd($Fasm, "fld [vdy]") ;st0=dy st1=l
FasmAdd($Fasm, "fdiv st0,st1") ;st0=dy/l
FasmAdd($Fasm, "fstp dword[vdy]") ;dy=dy/l
;dz=dz/l
FasmAdd($Fasm, "fild [vdz]") ;st0=dz st1=l
FasmAdd($Fasm, "fdiv st0,st1") ;st0=dz/l
FasmAdd($Fasm, "fstp dword[vdz]") ;dz=dz/l
;x=dx
FasmAdd($Fasm, "mov eax,[vdx]") ;
FasmAdd($Fasm, "mov [vx],eax") ;
;y=dy
FasmAdd($Fasm, "mov eax,[vdy]") ;
FasmAdd($Fasm, "mov [vy],eax") ;
;dy=y
FasmAdd($Fasm, "mov eax,[vy]") ;
FasmAdd($Fasm, "mov [vdy],eax") ;
;y=dz
FasmAdd($Fasm, "mov eax,[vdz]") ;
FasmAdd($Fasm, "mov [vy],eax") ;
;dx=x
FasmAdd($Fasm, "mov eax,[vx]") ;
FasmAdd($Fasm, "mov [vdx],eax") ;
;x=dy
FasmAdd($Fasm, "mov eax,[vdy]") ;
FasmAdd($Fasm, "mov [vx],eax") ;
;dy=x
FasmAdd($Fasm, "mov eax,[vx]") ;
FasmAdd($Fasm, "mov [vdy],eax") ;
;dz=y
FasmAdd($Fasm, "mov eax,[vy]") ;
FasmAdd($Fasm, "mov [vdz],eax") ;
;r=10000 ist konstante
;$A=$dx*$dx+$dy*$dy;
FasmAdd($Fasm, "fld [vdx]") ;st0=dx
FasmAdd($Fasm, "fmul st0,st0") ;st0=dx^2
FasmAdd($Fasm, "fld [vdy]") ;st0=dy
FasmAdd($Fasm, "fmul st0,st0") ;st0=dy^2 st1=dx^2
FasmAdd($Fasm, "fadd st0,st1") ;st0 =dx^2+dy^2
FasmAdd($Fasm, "fstp dword[va]") ;a=dx^2+dy^2
;$B=2*($dx*$ox+$dy*$oy) = 0;
;$c=-10000 =konstante
;$rd=Sqrt($B*$B-4*$A*$C);
FasmAdd($Fasm, "fld [minusvier]") ;st0=-4 69
FasmAdd($Fasm, "fmul [va]") ;st0=-4*a
FasmAdd($Fasm, "fmul [vc]") ;st0=-4*a*c
FasmAdd($Fasm, "fsqrt") ;st0=-4*a*c
; $q=-.5*($B-$rd)
FasmAdd($Fasm, "fldz ") ;st0=b=0 st1==rd
FasmAdd($Fasm, "fsub st0,st1") ;st0=(b-rd) st1=rd
FasmAdd($Fasm, "fmul [minuseinhalb]") ;st0=-0.5*(B-rd)=q
FasmAdd($Fasm, "fstp dword[vq]") ;
;~ ; $tu=5*ATan2($dy,$dx)/$Pi2;
FasmAdd($Fasm, "fld [vdx]") ;st0 =vdx
FasmAdd($Fasm, "fld [vdy]") ;
FasmAdd($Fasm, "fpatan") ;
FasmAdd($Fasm, "fmul [fuenf]") ;
FasmAdd($Fasm, "fldpi") ;
FasmAdd($Fasm, "fdivp st1,st0") ;
FasmAdd($Fasm, "fdiv [zwei]") ;st0=tu
FasmAdd($Fasm, "fistp [vtu]") ;tu
; $tv=$dz*$c/q/256;
FasmAdd($Fasm, "fld [vdz]") ;st0=dz
FasmAdd($Fasm, "fmul [vc]") ;
FasmAdd($Fasm, "fdiv [vq]") ;
FasmAdd($Fasm, "fdiv [v256]") ;
FasmAdd($Fasm, "fadd [va1]") ;tv
FasmAdd($Fasm, "fst [vtv]") ;tv=tv+a1
FasmAdd($Fasm, "fmul [v256]") ;tv
FasmAdd($Fasm, "fistp [vtv1]") ;tv
;stack cleanen
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "mov eax,[vtv1]") ;
FasmAdd($Fasm, "xor eax,[vtu]") ;
FasmAdd($Fasm, "and eax,0xFF") ;farbe von RR, GG und BB
;FasmAdd($Fasm, "ret 16");Funktionsende
;pixelfarbe (grauton) erstellen
FasmAdd($Fasm, "mov ebx,0xFF") ;alpha AA
FasmAdd($Fasm, "shl ebx,8") ;AA00
FasmAdd($Fasm, "or ebx,eax") ;AABB
FasmAdd($Fasm, "shl ebx,8") ;AABB00
FasmAdd($Fasm, "or ebx,eax") ;AABBGG
FasmAdd($Fasm, "shl ebx,8") ;AABBGG00
FasmAdd($Fasm, "or eax,ebx") ;AABBGGRR
;FasmAdd($Fasm, "ret 16");Funktionsende
;FasmAdd($Fasm, "mov eax,0xFF00FF00") ;AABBGGRR
FasmAdd($Fasm, "stosd") ;mov [edi],eax pixel in die bitmap schreiben
FasmAdd($Fasm, "dec ecx" ) ;schleifenzähler breite
FasmAdd($Fasm, "mov [vj],ecx" ) ;schleifenzähler breite
FasmAdd($Fasm, "jnz j_schleife") ;so lange bis 0
FasmAdd($Fasm, "dec edx") ;schleifenzähler hoehe
FasmAdd($Fasm, "mov [vi],edx" ) ;schleifenzähler breite
FasmAdd($Fasm, "jnz i_schleife") ;so lange bis 0
FasmAdd($Fasm, "ret 16");Programmende
[/autoit] [autoit][/autoit] [autoit];variablen, einige werden nicht gebraucht, habe aber versucht, das AutoItscript zu übernehmen
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "v256 dd 256.0") ;eigentlich konstanten....
FasmAdd($Fasm, "zwei dd 2.0")
FasmAdd($Fasm, "minusvier dd -4.0")
FasmAdd($Fasm, "fuenf dd 1280.0")
FasmAdd($Fasm, "minuseinhalb dd -0.5")
FasmAdd($Fasm, "bitmap dd 0")
FasmAdd($Fasm, "breite dd 0")
FasmAdd($Fasm, "hoehe dd 0")
FasmAdd($Fasm, "vhw dd 0")
FasmAdd($Fasm, "vhh dd 0")
FasmAdd($Fasm, "vo dd 0.0")
FasmAdd($Fasm, "vi dd 0.0")
FasmAdd($Fasm, "vj dd 0.0")
FasmAdd($Fasm, "vl dd 0.0")
FasmAdd($Fasm, "vdx dd 0.0")
FasmAdd($Fasm, "vdy dd 0.0")
FasmAdd($Fasm, "vdz dd 0.0")
FasmAdd($Fasm, "vx dd 0.0")
FasmAdd($Fasm, "vy dd 0.0")
FasmAdd($Fasm, "vr dd 10000.0")
FasmAdd($Fasm, "va dd 0.0")
FasmAdd($Fasm, "vb dd 0.0")
FasmAdd($Fasm, "vc dd -10000.0")
FasmAdd($Fasm, "vrd dd 0.0")
FasmAdd($Fasm, "vq dd 0.0")
FasmAdd($Fasm, "vt1 dd 0.0")
FasmAdd($Fasm, "vtu dd 0")
FasmAdd($Fasm, "vtv dd 0")
FasmAdd($Fasm, "vtv1 dd 0")
FasmAdd($Fasm, "va1 dd 0.00005")
$Binary = FasmGetBinary($Fasm) ;syntaxerror im Assembler abfangen abfangen
;~ If @Extended Then ;syntax-error aufgetreten
;~ $Error = FasmGetLastError()
;~ ConsoleWrite("Error Code:" & $Error[0] & @CRLF & "Error Message:" & $Error[1] & @CRLF & "Error Line:" & $Error[2] & @CRLF)
;~ Else ;syntax ok
ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
filedelete("test.bin") ;assembly für externen debugger
filewrite("test.bin",binarytostring(String(FasmGetBinary($Fasm))))
endfunc
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe DC und ptr und handle auf die Bitmapdaten
;by Andy
Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
Local $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
DllStructSetData($tBMI, "Width", $iwidth)
DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
DllStructSetData($tBMI, "Planes", 1)
DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', $DIB_RGB_COLORS, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
$ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
;_arraydisplay($adib)
_WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
Return $hcdc ;DC der Bitmap zurückgeben
EndFunc ;==>_CreateNewBmp32
übrigens habe ich auf einem AMD4850@2,5Ghz bei einer Fenstergröße von 320x320 ca 55FPS und bei 800x800 nur noch 5-6 FPS^^
und der JS-Code
<!doctype html>
<html>
<head>
<title>JS1k, 1k demo submission [165]</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="c"></canvas>
<script>
/*possan.se*2010*/
M=Math;
Sin=M.sin;
Cos=M.cos;
Sqrt=M.sqrt;
ATan2=M.atan2
Pi=M.PI;
Pi2=M.PI*2;
d=document;
d.body.style.backgroundColor="#222";
c=d.getElementById('c');
G=c.getContext('2d');
W=320;
H=320;
c.width=W;
c.height=H;
HW=W/2;
HH=H/2;
A0=A1=A2=A3=0;
ox=oy=oz=0;
tu=tv=0;
// rotate=function(t)
// {
// cc=Cos(t);
// ss=Sin(t);
// Z=X*cc-Y*ss;
// Y=X*ss+Y*cc;
// X=Z;
// };
setInterval(function()
{
b=G.getImageData(0,0,W,H);
d=b.data;
o=0;
for(i=0;i<H;i++)
for(j=0;j<W;j++)
{
dx=(j-HW)/W;
dy=(i-HH)/H;
dz=-1;
l=Sqrt(dx*dx+dy*dy+dz*dz);
dx/=l;
dy/=l;
dz/=l;
X=dx;
Y=dy;
//rotate(A0-A2);
dy=Y;
Y=dz;
dx=X;
X=dy;
//rotate(A3);
dy=X;
dz=Y;
R=100;
A=dx*dx+dy*dy;
B=2*(dx*ox+dy*oy);
C=ox*ox+oy*oy-R*R;
rd=Sqrt(B*B-4*A*C);
q=-.5*(B-rd);
t1=C/q;
tu=5*ATan2(dy,dx)/Pi2;
tv=dz*t1/256;
tv+=A1;
//tu*=5;
g=((tu*256)^(tv*256))&255;
//g&=255;
d[o++]=g;
d[o++]=g;
d[o++]=g;
d[o++]=255;
};
G.putImageData(b,0,0);
//A0+=0.015;
A1+=0.026;
//A2+=0.041;
//A3+=0.009;
},30);
</script>
</body>
</html>
Alles anzeigen
einfach als HTML speichern und aufrufen
ja, indem du entweder (in AutoIt) eine Struct anlegst und dort die Elemente per Index aufrufst (wie bei AutoIt) oder dein Array als
Zitat; angenommen, der inhalt von array[5] soll abgefragt werden
;mov eax,[basepointer_array + indexregister *4] ;4 byte pro wort
mov ebx,5 ;index
mov eax,[array+ebx*4] ;inhalt von array[5]
Pinguin, ich gehe einfach davon aus, daß die "Standard"-Befehle bei allen Microcontrollern und Prozessoren ähnlich sind, kannste einen, kannste alle^^
@Sprenger, schau mal IM FASM-Forum nach den Beispielen für DOS.
Eine EXE-Datei ist völlig anders aufgebaut und strukturiert wie eine COM-Datei. Um eine EXE zu erstellen, nehme ich immer eine "Vorlage", fülle diese mit Code und jage sie durch den Assembler (FASM oder FASMW)
1. Bsp für GUI (RAW-Mode, den keiner braucht...)
; Example of making 32-bit PE program as raw code and data
format PE GUI
entry start
section '.text' code readable executable
start:
push 0
push _caption
push _message
push 0
call [MessageBoxA]
push 0
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win32 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dd RVA _ExitProcess
dd 0
user_table:
MessageBoxA dd RVA _MessageBoxA
dd 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0
section '.reloc' fixups data readable discardable ; needed for Win32s
Alles anzeigen
2.Bsp: GUI per #include, so wie sich das gehört^^
Einfache EXEs brauchen diesen Aufwand nicht, da reicht ein
format MZ ;exe bauen
push cs
pop ds ;aktuelles datensegment holen
mov ah,9h ;"Zeichenkette darstellen" Funktion int 21
mov dx, nachricht1 ;Adresse Nachricht1
int 21h
; massig code^^
mov ah,9h ;Funktion int 21
mov dx, nachricht2 ;Adresse Nachricht2
int 21h
mov ax,4C00h ;exit
int 21h
nachricht1 db 'Hallo, ich bin ein String!',13,10,13,10,'$' ;2x CRLF strings immer mit $ terminieren
nachricht2 db 'Huhu, die 2. Zeile!',13,10,'$'
Alles anzeigen
um die Nachricht in die Konsole zu schreiben
Aber um mit dem Assembler EXE-files zu basteln ist das der falsche Thread, mach doch einen in OT auf!
Sehr schön, ggf sollten wir eine "Funktionssammlung" für schnelle Funktionen (mit Assemblerunterstützung) eröffnen.
Da ist ja schon einiges auch im "blauen" Forum zusammengekommen, Verschlüsselungen vor allem.
@Shadow, sehr nice kommentiert, das liest sich "wie ein Buch!". ![]()
ZitatHm also habe ich nur den Fehler gemacht es puffer zu nennen und mov eax,edi zu mov eax,puffer zu machen?
Was ist das denn für ein komischer Fehler
str ist reserviert, da Assemblerbefehl^^
Und wenn dein Zeiger EAX (EDI) auf das Ende des Strings zeigt, dann kann auch nur ab dort eingelesen werden.
FasmAdd($Fasm, "ende:");Label für Schleifen-/Funktions-Ende
FasmAdd($Fasm, "movsw");die 0 muss noch hinter den String
FasmAdd($Fasm, "lea eax,[edi-22]"); EAX= EDI-22 also wieder an den anfang des strings, wenn du nun die stringlänge zwischenspeicherst, kannst du auch [edi-ebx] machen!
FasmAdd($Fasm, "ret 4");Funktionsende
FasmAdd($Fasm, "puffer dw 1 dup(100)");hundert "words" reservieren für zielstring
LEA wollte ich im nächsten TUT-Teil abhandeln, ein sehr mächtiger Befehl, der einen Shift, zwei Additionen und einen Move in einem Befehl unterbekommt!
ZitatUnd was ist wenn man einen Uhralten CPU hat der noch kein SSE oder MMX unterstützt ? Schmiert die ganze Kiste ab oder gibts nur nen Error.
Da wird natürlich vorher abgefragt (per Assembler), ob die CPU SSE/SSE2/3/4 und/oder MMX überhaupt unterstützt. Sind nur einige Byte...
Zitat//Edit2: Haben AMD Prozessoren den gleichen Befehlssatz?
yepp, AMD hat übrigens wunderschöne Manuals...besonders die zur Optimierung sollten zu den Standardwerken für C bzw C++ - Programmierer gehören!
Bsp: SSE
Aber auch an den Seiten von Agner Fog (lesenswerte Manuals) wird man über kurz oder lang als Assemblerprogrammierer nicht vorbeikommen...
@ Bugfix, das hat sich ja erledigt^^
@TheShadowAE
$string="Hallo Test!"
[/autoit] [autoit][/autoit] [autoit]Dim $Fasm = FasmInit()
FasmReset($Fasm)
FasmAdd($Fasm, "use32")
FasmAdd($Fasm, "org " & FasmGetBasePtr($Fasm))
FasmAdd($Fasm, "mov eax,[esp+4]");Stringpointer aus Parameter zu eax
FasmAdd($Fasm, "mov esi,[eax]");str* zu str, außerdem nach esi, eax wird Rückgabe
FasmAdd($Fasm, "mov edi,puffer");edi muss Pointer auf einen String sein <-- Fehler
;
FasmAdd($Fasm, "schleife:");Label für Schleife
FasmAdd($Fasm, "cmp word[esi],0");Wenn Stringende
;~ FasmAdd($Fasm, "mov eax,dword[esi]")
;~ FasmAdd($Fasm, "ret 4");Funktionsende
FasmAdd($Fasm, "je ende");dann beende
FasmAdd($Fasm, "mov ax,word[esi]");sonst speichere das erste word in ax(eax=32 bit,ax=16bit)
FasmAdd($Fasm, "xor ax,25");verschlüssele es
FasmAdd($Fasm, "mov word[esi],ax");und schiebe es wieder zurück
FasmAdd($Fasm, "movsw");dann schiebe ein word in den Zielstring
FasmAdd($Fasm, "jmp schleife");und wiederhole die Schleife
;
FasmAdd($Fasm, "ende:");Label für Schleifen-/Funktions-Ende
FasmAdd($Fasm, "movsw");die 0 muss noch hinter den String
FasmAdd($Fasm, "mov eax,puffer");String aus edi, nach eax, damit der (de)codierte String zurückgegeben wird
FasmAdd($Fasm, "ret 4");Funktionsende
FasmAdd($Fasm, "puffer dw 1 dup(100)");hundert "words" reservieren für zielstring
$Ret = MemoryFuncCall("wstr", FasmGetFuncPtr($Fasm), "wstr*", $string)
msgbox(0,"kodieren XOR "&$string,$ret[0])
;_arraydisplay($ret)
$string=$ret[0] ;kodierter string
$Ret = MemoryFuncCall("wstr", FasmGetFuncPtr($Fasm), "wstr*", $string)
msgbox(0,"DEkodieren XOR "&$string,$ret[0])
exit
Mal abgesehen davon, daß du nur die falsche Adresse zurückgegebeb hattest (EDI zeigt ja nach der Schreiberei der Daten HINTER den String und nicht an den Anfang!) funktioniert das einwandfrei.
Du brauchst den "pufferl" aber nicht unbedingt, du überschreibst schreibst ja den "Eingangsstring" direkt.
Um übrigens "sauschnell" Strings bzw Speicher zu XORen, gibt es den SSE-Befehl XORPS oder PXOR, damit XORed man 128 Bit auf einen Streich. Aber SSE bzw MMX wollte ich später ins TUT integrieren^^
_GDIPlus_GraphicsGetSmoothingMode ()
[/autoit] ZitatNicht dass dann ein verschlafener IPod-Benutzer versucht sein Frühstücksei auf den IPod zu stellen,
was mich bei der Intelligenz einiger iPod-ler aber auch nicht sonderlich wundern würde ![]()
Aufruf von "Funktionen" mit CALL-Befehl, Beispiel Rekursion Fakultät
Im folgenden Beispiel wird der CALL-Befehl zum rekursiven Aufrufen einer Unterfunktion benutzt.
Fakultät => 5! = 5 * 4 * 3 * 2 * 1
Die Zahl, deren Fakultät bestimmt werden soll, wird an ECX übergeben.
Es wird geprüft, ob ECX 0 oder 1 ist, Ergebnis ist dann 1.
Weiterhin wird überprüft, ob ECX>12 ist (oder negativ). Dann wird als Ergebnis 0 ausgegeben.
12! ist deshalb oberes Limit, weil EAX nur maximal 32 Bit große Werte aufnehmen kann. (Hausaufgabe: erweitert das Programm so, daß der volle 64 (128 ) Bit große Zahlenraum ausgenutzt werden kann)
Der MUL-Befehl schreibt, wenn das Ergebnis einer Multiplikation > 32 Bit ist, den "Übertrag" in das (E)DX-Register.
Man hat also für das Ergebnis 64 Bit, und zwar EDX:EAX. Diese 64 Bit werden in die vorher von AutoIt angelegte Struct geschrieben.
Dann wird eine Funktion (Multiplizieren) geCALLed. Bei einem Call wird die aktuelle Adresse des Call-Befehls (EIP-Register IP=Instruction-Pointer) auf den Stack gepushed. Bei Stackoperationen inenrhalb der Funktion also den Stack im Auge behalten!
Die Funktion "Multiplizieren" multipliziert EAx=EAX*ECX, und DECrementiert ECX in jedem Durchlauf um 1.
Ist ECX = 0, wird die Rekursion unterbrochen, und per RET aus der Funktion zurückgesprungen. Das RET (des zugehörigen CALLs) popt nun den EIP vom Stack, damit wird das Programm an der Stelle fortgesetzt, an der der CALL-Aufruf stand.
Ist das Programm aus der letzten Rekursion zurückgekehrt, werden EDX und EAX in die 64-Bit-Struct des AutoItprogramms geschrieben und das Assemblerprogramm verlassen.
#include <FASM.au3>
#include <Array.au3>
#include <MemoryDll.au3>
;#include <GDIConstants.au3>
;es wird nur die Fakultät zw. 0 und 12 berechnet und als 64-Bit-zahl ausgegeben
$fakultaet=7
$struct=dllstructcreate("uint64") ;64 Bit-Zahl, hier wird das Ergebnis EDX:EAX gespeichert
$bytestruct=dllstructcreate("byte[8]", DllStructGetPtr($struct)) ;nur um zu sehen, wie 64-bit-Integer im Speicher stehen
;Verwendung von Rekursion
Dim $Fasm = FasmInit()
FasmReset($Fasm)
FasmAdd($Fasm, "use32")
FasmAdd($Fasm, "mov eax,1") ;falls Fakultaet von 0 oder 1, sind in EAX die oberen 32 Bit der struct
FasmAdd($Fasm, "mov edx,0") ;falls Fakultaet von 0 oder 1, sind in EDX die unteren 32 Bit der struct
FasmAdd($Fasm, "mov ecx,dword[esp+4]") ;ECX= fakultaet ;zähler für die rekursion, nach ecx rekursionen wieder zurück3
FasmAdd($Fasm, "cmp ecx,1") ;vergleiche, ob fakultaet=1
FasmAdd($Fasm, "jbe @f") ;ist die fakultaet kleiner oder gleich 1, dann zur nächsten Sprungmarke(ergebnis ausgeben)
FasmAdd($Fasm, "mov eax,0") ;falls Fakultaet>12, dann 0 als ergebnis ausgeben
FasmAdd($Fasm, "cmp ecx,12") ;vergleiche, ob fakultaet=12
FasmAdd($Fasm, "ja @f") ;ist die fakultaet>12, dann zur nächsten Sprungmarke(ergebnis ausgeben)
FasmAdd($Fasm, "mov eax,ecx") ;ECX mal soll EAX=EAX*ECX ausgeführt werden, ECX wird immer um 1 reduziert, bis 0
FasmAdd($Fasm, "dec ecx") ;ECX=ECX-1
FasmAdd($Fasm, "call Multiplizieren") ;mit CALL die Funktion aufrufen, mit RET aus der Funktion wieder raus EAX=EAX*ECX
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "@@: mov edi,[esp+8]") ;ESI=Adresse struct @@ ist eine universelle sprungmarke
FasmAdd($Fasm, "mov dword[edi],eax") ;in der struct obere 32 Bit der multiplikation setzen
FasmAdd($Fasm, "mov dword[edi+4],edx") ;in der struct untere 32 Bit der multiplikation setzen
FasmAdd($Fasm, "ret ") ;Programm beenden, ergebnis in EAX, falls memorydllcall, kommt NUR HIER der ret 8
FasmAdd($Fasm, "Multiplizieren:") ;Adresse der Funktion EIP(Instructionpointer) auf den Stack
; FasmAdd($Fasm, "push edi") ;Beispiele: Im zweifelsfall alles sichern, was nicht bei 10 auf den Bäumen ist, natürlich nicht die rekursionsvariablen^^
FasmAdd($Fasm, "mov edx,0") ;EDX wird bei der folgenden Multiplikation ggf zerstört!
FasmAdd($Fasm, "mul ecx") ;EDX:EAX=EAX*ECX multiplizieren und aufsummieren, EDX wird durch MUL zerstört, wenn ergebnis >32 Bit!
; FasmAdd($Fasm, "pop edi") ;alles was vorher gesichert wurde, wiederherstellen
FasmAdd($Fasm, "dec ecx") ;Abbruchkriterium, wenn....
FasmAdd($Fasm, "jz zurueck") ;...ECX=0 (Jump if Zero) dann nach Zurueck, ansonsten weiter
FasmAdd($Fasm, "call Multiplizieren") ;Rekursion, Funktion aufrufen
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "zurueck:") ;label fürs rausspringen aus der Rekursion
FasmAdd($Fasm, "ret") ;das passende RET zum CALL, ein Rekursionsschritt zurück pop EIP (führt dazu, dass an der gepopten adresse weitergemacht wird
$Binary = FasmGetBinary($Fasm) ;syntaxerror im Assembler abfangen abfangen
If @Extended Then ;syntax-error aufgetreten
$Error = FasmGetLastError()
ConsoleWrite("Error Code:" & $Error[0] & @CRLF & "Error Message:" & $Error[1] & @CRLF & "Error Line:" & $Error[2] & @CRLF)
Else ;syntax ok
ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
filedelete("test.bin") ;assembly für externen debugger
filewrite("test.bin",binarytostring(String(FasmGetBinary($Fasm))))
$tCodeBuffer = DllStructCreate("byte[512]") ;Speicher für den assemblercode belegen
DllStructSetData($tCodeBuffer, 1, String(FasmGetBinary($Fasm)))
$a = DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"int",$fakultaet ,"ptr",DllStructGetPtr($struct), "int", 0,"int",0);bytecode aufrufen, rückgabe in a[0]
[/autoit] [autoit][/autoit] [autoit]ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : DllStructGetData($bytestruct,1) = ' & DllStructGetData($bytestruct,1) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
msgbox(0,"EAX = "&$a[0],"Fakultät von "&$fakultaet&" = "&DllStructGetData($struct,1))
_arraydisplay($a)
endif
FasmExit($Fasm)
exit
[/autoit]
Die Überprüfung der Assemblersyntax habe ich auch implementiert.
//EDIT//
das ganze als AutoIt-Funktion
;Fakultät im Integerbereich
[/autoit] [autoit][/autoit] [autoit]$fac=_asmFakultaet(3)
MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$fac' & @lf & @lf & 'Return:' & @lf & $fac) ;### Debug MSGBOX
func _asmFakultaet($int)
;http://www.autoit.de/index.php?page…3353#post183353
if not IsInt($int) then return seterror(-1,0,-1)
if $int<0 or $int>12 then return seterror(-1,0,-1)
$bytecode="0xB801000000BA000000008B4C240483F9017612B80000000083F90C770889C849E80A0000008B7C24088907895704C3BA00000000F7E1497405E8F1FFFFFFC3"
$tCodeBuffer = DllStructCreate("byte["&stringlen($bytecode)-1&"]") ;Speicher für den assemblercode belegen
DllStructSetData($tCodeBuffer, 1,$bytecode) ;assemblercode in speicher schreiben
$struct=dllstructcreate("uint64") ;64 Bit-Zahl, hier wird das Ergebnis EDX:EAX gespeichert
$a = DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"int",$int ,"ptr",DllStructGetPtr($struct), "int", 0,"int",0);bytecode aufrufen, rückgabe in a[0]
if @error then return seterror(-1,0,-1)
return $a[0]
endfunc