1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Andy

Beiträge von Andy

  • _IELinkClickByText Problem

    • Andy
    • 25. August 2010 um 09:45
    Zitat

    Auf 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?

  • welcber browser ist installiet

    • Andy
    • 24. August 2010 um 20:35

    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

  • welcber browser ist installiet

    • Andy
    • 24. August 2010 um 18:14

    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"^^

    Spoiler anzeigen
    [autoit]

    #include <File.au3>
    #include <Array.au3>
    $browserinfo=__GetBrowserInfo()
    _arraydisplay($browserinfo)

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit]
  • Assembler Hilfe-Thread

    • Andy
    • 24. August 2010 um 17:50

    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 :rofl: , aber das lernt man dann SEHR schnell^^

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 24. August 2010 um 15:49
    Zitat

    Dafü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^^ 8o

    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^^

  • Assembler Hilfe-Thread

    • Andy
    • 24. August 2010 um 15:42

    @sprenger, wg deinem comfile....guck mal nach, was der INT 20 macht nach dem 1. INT21 :thumbup:

  • Assembler Hilfe-Thread

    • Andy
    • 24. August 2010 um 15:39
    Spoiler anzeigen
    [autoit]

    #include "FASM.au3"
    #include <Array.au3>
    $Fasm = FasmInit()
    FasmReset($Fasm)

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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)

    [/autoit] [autoit][/autoit] [autoit]

    Func fa($str) ; Nur für die bequemlichkeit ^^
    FasmAdd($Fasm, $str)
    EndFunc ;==>fa

    [/autoit] [autoit][/autoit] [autoit]

    FasmExit($Fasm)

    [/autoit]
  • Assembler Hilfe-Thread

    • Andy
    • 24. August 2010 um 14:42

    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:

    [autoit]

    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)

    [/autoit]
  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 24. August 2010 um 12:38

    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:

    Spoiler anzeigen
    [autoit]

    ;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)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
    Local $H = 332, $W = 332
    ; Initialize GDI+
    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("GDI+ Test", $W, $H)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($W, $H, $hGraphics)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    ; Using antialiasing
    ;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 0)
    ; Create a Brush object
    Local $hBrush = _GDIPlus_BrushCreateSolid()

    [/autoit] [autoit][/autoit] [autoit]

    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]

    [/autoit] [autoit][/autoit] [autoit]

    $zwonulldrei=203.718330632686
    $nulldrei=0.390625
    ;$a1=0.07

    [/autoit] [autoit][/autoit] [autoit]

    While 1;Sleep(10)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000)

    [/autoit] [autoit][/autoit] [autoit]

    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)

    [/autoit] [autoit][/autoit] [autoit]

    Next
    Next
    $A1 += 0.07

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $W, $H)
    $fps+=1
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $A1 = ' & $A1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    func _FPS()
    winsettitle($hgui,"",$FPS)
    $FPS=0
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Rotate($t)
    $cc = Cos($t)
    $ss = Sin($t)
    $z = $x * $cc - $y * $ss
    $y = $x * $ss + $y * $cc
    $x = $z
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    func atan2($y,$x)
    return (2*atan($y/($x+sqrt($x*$x+$y*$y))))
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    ; Clean up
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)

    [/autoit] [autoit][/autoit] [autoit]

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()
    Exit
    EndFunc

    [/autoit]

    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!

    Spoiler anzeigen
    [autoit]

    #include <FASM.au3>
    #include <MemoryDll.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <StructureConstants.au3>
    #include <GDIConstants.au3>
    #include <array.au3>
    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    $b=520
    $h=520

    [/autoit] [autoit][/autoit] [autoit]

    global $Fasm = FasmInit(), $FPS
    _createbytecode() ;assemblercode erstellen

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    $hgui=guicreate("",$b,$h,1,1)
    $hdc_gui=_WinAPI_GetDC($hgui)
    guisetstate()

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    adlibregister("_fps",1000) ;FramesPerSecond

    [/autoit] [autoit][/autoit] [autoit]

    $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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    func _fps()
    winsettitle($hgui,"",$fps)
    $fps=0
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    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") ;

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($Fasm, "FINIT") ;copro init

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($Fasm, "mov dword[vi],0") ;schleifenzähler
    FasmAdd($Fasm, "mov dword[vj],0") ;

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    ;~ ;$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

    [/autoit] [autoit][/autoit] [autoit]

    ;$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

    [/autoit] [autoit][/autoit] [autoit]

    ;$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

    [/autoit] [autoit][/autoit] [autoit]

    ;$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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($Fasm, "dec edx") ;schleifenzähler hoehe
    FasmAdd($Fasm, "mov [vi],edx" ) ;schleifenzähler breite
    FasmAdd($Fasm, "jnz i_schleife") ;so lange bis 0

    [/autoit] [autoit][/autoit] [autoit]

    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")

    [/autoit] [autoit][/autoit] [autoit]

    $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))))

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit]
  • Selbst aktuellisierende Uhr

    • Andy
    • 24. August 2010 um 01:05

    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

    [autoit]

    _NowDate() und _NowCalcDate()

    [/autoit]

    interessant...

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 24. August 2010 um 00:46

    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:

    Code
    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^^)

    Spoiler anzeigen
    [autoit]

    ;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)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
    Local $H = 132, $W = 132
    ; Initialize GDI+
    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("GDI+ Test", $W, $H)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($W, $H, $hGraphics)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    ; Using antialiasing
    ;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 0)
    ; Create a Brush object
    Local $hBrush = _GDIPlus_BrushCreateSolid()

    [/autoit] [autoit][/autoit] [autoit]

    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]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ $A2 += 0.041
    ;~ $A3 += 0.009
    Next
    $A1 += 0.07

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $W, $H)
    $fps+=1
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $A1 = ' & $A1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    func _FPS()
    winsettitle($hgui,"",$FPS)
    $FPS=0
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Rotate($t)
    $cc = Cos($t)
    $ss = Sin($t)
    $z = $x * $cc - $y * $ss
    $y = $x * $ss + $y * $cc
    $x = $z
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    func atan2($y,$x)
    return (2*atan($y/($x+sqrt($x*$x+$y*$y))))
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    ; Clean up
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)

    [/autoit] [autoit][/autoit] [autoit]

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()
    Exit
    EndFunc

    [/autoit]

    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! )

    Spoiler anzeigen
    [autoit]

    #include <FASM.au3>
    #include <MemoryDll.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <StructureConstants.au3>
    #include <GDIConstants.au3>
    #include <array.au3>
    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    $b=520
    $h=520

    [/autoit] [autoit][/autoit] [autoit]

    global $Fasm = FasmInit(), $FPS
    _createbytecode() ;assemblercode erstellen

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    $hgui=guicreate("",$b,$h,1,1)
    $hdc_gui=_WinAPI_GetDC($hgui)
    guisetstate()

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    adlibregister("_fps",1000) ;FramesPerSecond

    [/autoit] [autoit][/autoit] [autoit]

    $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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    func _fps()
    winsettitle($hgui,"",$fps)
    $fps=0
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    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") ;

    [/autoit] [autoit][/autoit] [autoit]

    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") ;

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    ;~ ;$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]") ;

    [/autoit] [autoit][/autoit] [autoit]

    ;~ ; $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

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($Fasm, "dec edx") ;schleifenzähler hoehe
    FasmAdd($Fasm, "mov [vi],edx" ) ;schleifenzähler breite
    FasmAdd($Fasm, "jnz i_schleife") ;so lange bis 0

    [/autoit] [autoit][/autoit] [autoit]

    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")

    [/autoit] [autoit][/autoit] [autoit]

    $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))))

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit]

    ü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

    Spoiler anzeigen
    PHP
    <!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

  • Assembler Hilfe-Thread

    • Andy
    • 23. August 2010 um 23:53

    ja, indem du entweder (in AutoIt) eine Struct anlegst und dort die Elemente per Index aufrufst (wie bei AutoIt) oder dein Array als

    Code
    Array dd 1 dup(100)   ;erstellt ein  "Array" von 100 dwords
    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]

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 22. August 2010 um 20:25

    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...)

    Spoiler anzeigen
    Code
    ; 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^^

    Spoiler anzeigen
    Code
    include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here
    
    
    .code
    
    
      start:
    	invoke	MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK
    	invoke	ExitProcess,0
    
    
    .end start
    Alles anzeigen

    Einfache EXEs brauchen diesen Aufwand nicht, da reicht ein

    Spoiler anzeigen
    Code
    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!

  • Assembler Hilfe-Thread

    • Andy
    • 22. August 2010 um 18:02

    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!". :thumbup:

  • Assembler Hilfe-Thread

    • Andy
    • 22. August 2010 um 14:06
    Zitat

    Hm 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.

    [autoit]

    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

    [/autoit]

    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!

  • Assembler Hilfe-Thread

    • Andy
    • 22. August 2010 um 13:56
    Zitat

    Und 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...

  • Assembler Hilfe-Thread

    • Andy
    • 22. August 2010 um 13:36

    @ Bugfix, das hat sich ja erledigt^^

    @TheShadowAE

    Spoiler anzeigen
    [autoit]

    $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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $Ret = MemoryFuncCall("wstr", FasmGetFuncPtr($Fasm), "wstr*", $string)
    msgbox(0,"kodieren XOR "&$string,$ret[0])
    ;_arraydisplay($ret)

    [/autoit] [autoit][/autoit] [autoit]

    $string=$ret[0] ;kodierter string
    $Ret = MemoryFuncCall("wstr", FasmGetFuncPtr($Fasm), "wstr*", $string)
    msgbox(0,"DEkodieren XOR "&$string,$ret[0])
    exit

    [/autoit]

    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 Qualität verbessern

    • Andy
    • 22. August 2010 um 10:34
    [autoit]

    _GDIPlus_GraphicsGetSmoothingMode ()

    [/autoit]
  • Apple lässt Eierbecher "eiPott" verbieten

    • Andy
    • 21. August 2010 um 15:53
    Zitat

    Nicht 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 :thumbup:

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 21. August 2010 um 14:46

    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.

    Spoiler anzeigen
    [autoit]

    #include <FASM.au3>
    #include <Array.au3>
    #include <MemoryDll.au3>
    ;#include <GDIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;es wird nur die Fakultät zw. 0 und 12 berechnet und als 64-Bit-zahl ausgegeben
    $fakultaet=7

    [/autoit] [autoit][/autoit] [autoit]

    $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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;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)

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $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))))

    [/autoit] [autoit][/autoit] [autoit]

    $tCodeBuffer = DllStructCreate("byte[512]") ;Speicher für den assemblercode belegen
    DllStructSetData($tCodeBuffer, 1, String(FasmGetBinary($Fasm)))

    [/autoit] [autoit][/autoit] [autoit]

    $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))

    [/autoit] [autoit][/autoit] [autoit]

    _arraydisplay($a)
    endif
    FasmExit($Fasm)

    [/autoit] [autoit][/autoit] [autoit]

    exit

    [/autoit]


    Die Überprüfung der Assemblersyntax habe ich auch implementiert.

    //EDIT//
    das ganze als AutoIt-Funktion

    Spoiler anzeigen
    [autoit]

    ;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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit]

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™