Drei Fragen:
1. Wo finde ich <ASM.au3> und <FASM.au3> ?
2. Worin besteht der Unterschied zwischen beiden?
3. Wo finde ich eine Beschreibung der Assemblerbefehle, die ich hier verwenden kann?
Schon einmal recht vielen Dank für eine Antwort.
Assembler
-
DOheim -
12. Dezember 2015 um 14:38 -
Erledigt
-
-
1. Eine <ASM.au3> kenne ich persönlich nicht. Die <FASM.au3> ist ein Include die an vielen Stellen in unterschiedlichen Versionen hochgeladen wurde. Aus dem englischen Forum bekommt man das Original.
2. FASM.au3 bietet einen Wrapper um mit OP-Codes zu hantieren (es gibt also kein vollständiges Programm, sondern eher einzelne Funktionen die dann in ASM geschrieben sind)
3. "Hier" kann man die gleichen Assemblerbefehle verwenden wir überall sonst auch. Um die spezielles zu fasm zu finden würde ich einfach deren Webseite benutzen. http://flatassembler.net/Ich habe vor geraumer Zeit mal einen wrapper für die FASM.au3 geschrieben. Dadurch wird die Handhabung nochmal ein Stück vereinfacht (meiner Meinung nach).
AutoIt & ASMlg
M -
Erst einmal recht herzlichen Dank für Deine Antwort.
Dein FASM klapp ja prima. So habe ich jedenfalls erst einmal das BeispielCode
Alles anzeigen#include <FASM.au3> $zahl1=Inputbox("Zahl","Zahl1") $zahl2=Inputbox("Zahl","Zahl2") $Fasm = FasmInit() FasmReset($Fasm) FasmAdd($Fasm, "use32") FasmAdd($Fasm, "mov eax, [esp+4]") FasmAdd($Fasm, "mov edi, [esp+8]") FasmAdd($Fasm, "add eax, edi") FasmAdd($Fasm, "ret") $bytecode=FasmGetBinary($Fasm) $tCodebuffer=dllstructcreate("byte["&stringlen($Bytecode)/2-1&"]") dllstructsetdata($tCodeBuffer,1,$Bytecode) $Ret= DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "int", $zahl1, "int", $zahl2, "int", 0, "int", 0) MsgBox(0,"Ergebnis",$Ret[0])
von
[Link entfernt]zum Laufen bekommen. Jetzt muss ich mir das allerdings alles erst einmal zu Gemüte ziehen.
Ich habe in den 60er, 70er und 80er Jahren nur mit Assembler gearbeitet. Die "Großrechner" hatten einen gegenüber unseren PCs so geringe Arbeitsspeicher (1963: 2K Bytes, 1972: 64K Bytes), dass man mit jedem Byte geizten musste und keine höhere Sprache verwenden konnte. Ja und jetzt muss ich mit der Ass-Programmierung ganz von vorne anfangen. Aber um mit Bitmaps (mit beispielsweise 3 MByte) zu arbeiten, kommt man um Ass nicht herum.
Bestimmt werde ich bald mit weiteren Fragen kommen.
Also nochmals vielen Dank!Edit Oscar: Link entfernt. Bitte keine Links zu Botforen!
-
Hi
hier bekommst du AssembleIt2_64, mit integriertem Debugger und 64-Bit-Modus...
Ich habe die FASM.dll gewrappert, das ist sehr schnell.Die verwendbaren Assemblerbefehle sind hier gut erklärt, für Anfänger, welche SSE-Befehle einsetzen wollen gibts nur eine richtige Referenz, das "alte" AMD-Dokument. Wer eine noch bessere optisch verständliche Darstellung von SSE-Befehlen kennt, bitte Link posten!
Der Einsatz des Debuggers ist in einem Beispielscript verdeutlicht.
Man kann an beliebiger Stelle den ASM-code unterbrechen und die Registerinhalte werden in einer GUI angezeigt. Man kann sogar bestimmte Kriterien angeben, bis zu denen der Code laufen soll, bis die GUI angezeigt wird.In den Beispielen wird exemplarisch der FASM-Funktionsumfang dargestellt, also Macros, Funktionen uvm.
Mir leistet die vorliegende Funktion gute Dienste, ich beschränke mich auch nur auf eine Handvoll ASM-Befehle
Für absolute Anfänger ist HIER der Einstieg^^
-
Nur um es mal vorwegzunehmen: elitepvpers ist eine Seite für Personen die ihre Fähigkeiten benutzen um anderen zu schaden (sehr vornehm ausgedrückt). Da ich vermute, dass der Verweis keine Absicht ist, also kann man darüber hinwegsehen. Bitte entferne aber den Link zu diesem Forum, da soetwas gegen unsere Forenregeln verstößt.
lg
M -
Vielen Dank Euch beiden, Andy und Mars!
Jetzt habe ich ja reichlich Material für mein Assembler-Studium.
Wie kann man denn erkennen, dass z.B. elitepvpers eine schädliche Seite ist?
Hat diese etwa auf meinem PC schon einen Schaden angerichtet?
Dann müsste ich mir meinen letzten System-Backup zurückholen.PS.: Der Debugger ist ja eine feine Sache!
-
Wie kann man denn erkennen, dass z.B. elitepvpers eine schädliche Seite ist?
Naja, ob die Website irgendwelche Schäden verursacht, kann ich nicht sagen
Mars spielte nur darauf an, dass es dort massig Threads und User zu Themen gibt, die es hier bei uns bzgl. Forenregeln nicht in die Top Ten schaffen
Sicherlich gibt es auch dort gute Programmierer, aber irgendwann werden auch die erwachsen und wandern ab....
Und die "dummen" Fragen sowie dazugehörigen Antworten bzw. Halbwissen überwiegen, also nichts, was man unbedingt in der Schnellwahl braucht!Jetzt habe ich ja reichlich Material für mein Assembler-Studium.
Was willst du machen bzw. wozu Assembler in Kombination mit AutoIt?
Zitat von DOheimPS.: Der Debugger ist ja eine feine Sache!
Wenn du das Scriptfenster von Scite so verkleinerst, dass es neben das Debugfenster passt, wirst du feststellen, dass bei jedem _ASMdebug_() im ASM-code in die entsprechende Zeile in Scite gesprungen wird...
Damit ist es auch möglich, längere Sources zu debuggen und trotzdem immer zu wissen, wo man sich gerade im Code befindet!Btw. ich suche immer noch eine(n), der das Debugfenster mal "aufräumt"
-
Lieber Andy,
Wenn du das Scriptfenster von Scite so verkleinerst, dass es neben das Debugfenster passt, wirst du feststellen, dass bei jedem _ASMdebug_() im ASM-code in die entsprechende Zeile in Scite gesprungen wird...
Das war mir gleich aufgefallen. Total gut!
Was willst du machen bzw. wozu Assembler in Kombination mit AutoIt?
Ich habe vor längerer Zeit ein Bitmap-Programm geschrieben, das mehrere Aufgaben erfüllt.
Alles funktioniert zur Zufriedenheit. Aber die eine Aufgabe dauert ewig:
An einem Mini-Beispiel erläutert:
Ich habe diese Bitmap:
aaa1.bmp
Das Programm ermittelt nun alle vorkommenden Farben (auf Wunsch auch Farbbereiche) und zeigt sie so an:
aaa2.bmp
Nun kann man nach belieben Farben verändern.
Und dieser ganze Prozess (in AutoIt geschrieben) dauert bei großen Bitmaps recht lange.
Die ganze Organisation rundherum macht sich mit AutoIt recht gut, aber das Filetstück mit der Bearbeitung von Millionen Bitmap-Pixeln möchte ich mit Assembler lösen.Kannst Du mir einen Tipp geben, wo ich ein Verzeichnis der möglichen Parameter-Typen für die Funktion _AssembleIt2 finde.
"int_ptr" scheint ja eine ganze Zahl zu bedeuten.
Was müsste man angeben, wenn man den Inhalt einer Bitmap-Datei als String (den man mit FileRead gelesen hat) übergeben möchte? -
Da ich meistens ohne AssembleIt programmiere kann ich da keine gute Auskunft geben. Habe dir aber ein kleines Beispiel geschrieben das in deinem Beispielbild via ASM eine Farbe ersetzt. Genutzt wird dafür eine kleine UDF die als Schnittstelle zwischen GDI+ und ASM dient.
lg
M -
Naja,
zunächst, willkommen im Club!
Bitmapbearbeitung mittels ASM ist hier im Forum die Anwendung Nummer eins (bei den Gestörten, die heutzutage noch Assembler benutzen^^ )Zunächst, du brauchst lediglich den 32-Bit-Modus, der ist sehr einfach und du musst dich nicht mit dem 64-Bit-Gedöns rumschlagen.
Nur zur ungefähren Hausnummer bzgl. Geschwindigkeit, ein Faktor 1000 schneller als AutoIt ist bei Pixelbearbeitung "normal".Das Procedere ist sehr simpel, Bilddatei (BMP, PNG, JPEG usw.) laden, dort erhält man dann neben diversen Daten der Datei (Größe, Farbraum usw.) auch den HDC (device Context) um die geladene/bearbeitete Bitmap in eine GUI zu blitten und als wichtigstes den Pointer zum Anfang der ARGB (BRGA)-Daten.
Die Parameter zur Übergabe an AssembleIt kannst du aus der Hilfe zu DllStructCreate() entnehmen.
Eigentlich Mumpitz, DWORD/UINT funktioniert immer, solange man nur "32-Bit-Zahlen" an AssembleIt übergeben will...Ich werde heute Abend mal ein kleines rudimentäres Script zur universellen Bildbehandlung einstellen, das hilft dir sicher weiter.
Die übergebenen 32-Bit-Parameter werden per Stack übergeben, im ASM-Code also per ESP+4, ESP+8, ESP+12 eingelesen, danach fängt das Bitgeschiebe an^^
Stack aufräumen übernimmt AssembleIt, ein simples RET reicht immer.Mehrere Rückgabeparameter von ASM nach Autoit werden über eine Struct realisiert. benötigt man nur einen Wert, ist das EAX-Register gefragt.
AutoIt
Alles anzeigen;eine bestimmte Farbe auf dem gesamten Bildschirm zählen #include <assembleit2_64.au3> #cs _numberofpixel use32 mov edi,[esp+4] ;pointer pixel mov ecx,[esp+8] ;number pixel BxH mov ebx,[esp+12] ;color pixel mov eax,0 ;counter pixel with color _next: ;label: for ecx=numberpixel to 0 cmp ebx,[edi+ecx*4] ;is dword=color ? (4 Bytes per pixel) jne _no ;no, next Pixel add eax,1 ;yes, one more found _no: ;no pixel with color was found sub ecx,1 ;next pixel jnz _next ;jump if not zero (ecx=0) to label ret ;return, returns eax #ce ;binary aus assemblercode erstellen (für dllcalladdress benötigt, nur beispiel) $binarycode = _AssembleIt2("retbinary", "_numberofpixel") ;gibt nur den code zurück ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ;nur für dllcalladdress() benötigt, den binarycode braucht man nur ein mal erstellen Global $tCodeBuffer = DllStructCreate("byte[" & StringLen($binarycode) / 2 - 1 & "]") ;reserve Memory for opcodes DllStructSetData($tCodeBuffer, 1, $binarycode) ;"0x8B7C24048B542408B900000000BB00000000B8FF000000C1E00809D0C1E00809D8C1E00809C8890783C7044381FB0001000075DE4181F90001000075D0C3") ;write opcodes into memory $height = @DesktopHeight ;Bildschirmdaten $width = @DesktopWidth $col = 0xFF000000 ; AARRGGBB gesuchte Farbe ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $col = ' & Hex($col, 8) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console $DC_screen = _WinAPI_GetDC(0) ;Device Context vom Screen Global $ptr, $hbmp ;pointer auf die pixel, handle bitmap $DC_bitmap = _CreateNewBmp32($height, $width, $ptr, $hbmp);leere Bitmap erstellen _WinAPI_BitBlt($DC_bitmap, 0, 0, $height, $width, $DC_screen, 0, 0, 0xCC0020);$srccopy copy screenpixel into bitmap ;entweder Assembleit benutzen, assembliert code während der Laufzeit JIT $t = TimerInit() Local $ret = _AssembleIt2("uint", "_numberofpixel", "ptr", $ptr, "int", $width * $height, "dword", $col) ConsoleWrite("_AssembleIt2() Anzahl Pixel = " & $ret & " Zeit [ms] = " & Int(1000 * TimerDiff($t)) / 1000 & @CRLF) ;### Debug Console ;oder den schnelleren Dllcalladdress $t = TimerInit() $ret = DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer), "ptr", $ptr, "int", $width * $height, "dword", $col) ConsoleWrite("DllCallAddress() Anzahl Pixel = " & $ret[0] & " Zeit [ms] = " & Int(1000 * TimerDiff($t)) / 1000 & @CRLF & @CRLF) ;### Debug Console _DeleteBitmap32($DC_bitmap, $ptr, $hbmp) ;Ressourcen freigeben Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette DllStructSetData($tBMI, 2, $iwidth) DllStructSetData($tBMI, 3, -$iheight) ;minus =standard = bottomup DllStructSetData($tBMI, 4, 1) DllStructSetData($tBMI, 5, 32) ;32 Bit = 4 Bytes => AABBGGRR $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, '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 _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC Return $hcdc ;DC der Bitmap zurückgeben EndFunc ;==>_CreateNewBmp32 Func _DeleteBitmap32($DC, $ptr, $hbmp) _WinAPI_DeleteDC($DC) _WinAPI_DeleteObject($hbmp) $ptr = 0 EndFunc ;==>_DeleteBitmap32
-
Hallo Andy und Mars,
zunächst vielen Dank für die Mühe, die Ihr Euch mit mir gebt.
Zu dem Beispiel von Andy:
Ich bekomme es einfach nicht zum Laufen. Ich habe Verschiedenes herumexperimentiert, aber es läuft immer darauf hinaus wie im Screenshot dargestellt.Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist. Die beiden
- ConsoleWrite ('@@ Debug ...
erscheinen, aber
- ConsoleWrite("_AssembleIt2() ...
nicht mehr und das Program bricht mit einem Fehler ab..
Gestartet habe ich das Programm über Tools/Go. Ich habe es auch kompiliert und dann gestartet, das klappt aber auch nicht.
Problem ist, dass ich bisher nicht mit WinApi- und Dll-Funktionen gearbeitet habe, und es mir schwer fällt, alles so richtig zu kapieren.
Was habe ich falsch gemacht? Vielleicht kannst Du mir auf die Sprünge helfen. -
Ich kann deinen Screenshot leider nicht laden/betrachten.
Welche Autoitversion benutzt du?Gestartet wird ein Script einfach mit der F5-Taste...
Versuche mal, den 32-Bitmodus zu erzwingen per
#AutoIt3Wrapper_UseX64=n
in der ersten Zeile!
Inwieweit bestehen spezielle User-Restriktiven auf deinem Rechner? Bist du als User mit eingeschränkten Rechten eingeloggt?
Welches Betriebssystem nutzt du? -
Als Link zu dem Screenshot funktionieret dieser:
https://autoit.de/index.php/Atta…creenshot6-JPG/Übrigens dauert es zwischen den Zeilen:
@@ Debug(48) : $col = FF000000
>Error code: 0und:
!>10:56:48 AutoIt3.exe ended.rc:-1073741819
ein paar Sekunden. Also irgend etwas macht er.
AutoIt-Version: Stabil 3.3.12.0 (Stand 17.9.14)
Betriebssystem: Windows 7
Durch
#AutoIt3Wrapper_UseX64=n
ändert sich nichts.Bin als Administrator eingeloggt. Habe in dieser Hinsicht auch sonst keine Schwierigkeiten.
Dein Beispiel "Debugger Beispiele.au3" funktioniert ja auch einwandfrei.
Auch die Beispiele "Beispiel_1 ASM-Code AssembleIt2 Farbpalette.au3" usw. funktionieren.Gruß
DieterPS.:
Ich habe mal drei Sleep-Befehle eingefügt.
Jetzt klappt es:
screenshot2.JPG
Link: https://autoit.de/index.php/Atta…creenshot2-JPG/
Woran mag das wohl liegen?
Nochmals herzlichen Gruß -
Link: autoit.de/index.php/Attachment/83432-screenshot2-JPG/
Woran mag das wohl liegen?DAS ist eine sehr gute Frage....
Assembler aus Geschwindigkeitsgründen zu benutzen um dann Sleeps von einer Sekunde einzufügen ist...ööööhhmmm...suboptimalUm mal weiter zu forschen...
Der Code wird einwandfrei assembliert, und sicherlich wird auch die Bitmap angelegt und mit Daten gefüllt.Kommentiere mal die Zeilen mit $ret = _AssembleIt2(blablub)
und die darauffolgende Consolewrite aus, so dass nur der Dllcall übrig bleibt, alle Sleeps auskommentieren.
Funktioniert das?Wenn es also am Aufruf von _AssembleIt() liegt, bitte mal ganz oben im Assemblercode nach dem Use32 ein RET eintragen, dann nochmal testen, immer noch ohne die Sleeps.
-
Kommentiere mal die Zeilen mit $ret = _AssembleIt2(blablub)
und die darauffolgende Consolewrite aus, so dass nur der Dllcall übrig bleibt, alle Sleeps auskommentieren.
Funktioniert das?Funktioniert nicht. Siehe Sreenshot1
Link: https://autoit.de/index.php/Atta…creenshot1-JPG/Aktiviere ich aber den Sleep BBB dann geht es. Siehe Sreenshot2
Link: https://autoit.de/index.php/Atta…creenshot2-JPG/
Allerdings ist die Anzahl Pixel =0:DllCallAddress() Anzahl Pixel = 0 Zeit [ms] = 2.147
Wenn es also am Aufruf von _AssembleIt() liegt, bitte mal ganz oben im Assemblercode nach dem Use32 ein RET eintragen, dann nochmal testen, immer noch ohne die Sleeps.
Funktioniert. Siehe Sceenshot3
Link: https://autoit.de/index.php/Atta…creenshot3-JPG/Auch wenn ich _AssembleIt2() und die 3 Sleeps wieder aktiviere, kommt Anzahl Pixel = 0
_AssembleIt2() Anzahl Pixel = 0 Zeit [ms] = 3.817
DllCallAddress() Anzahl Pixel = 0 Zeit [ms] = 1.88Übringens klappt es auch mit den drei Sleep nicht immer.
Rätselhaft!
Du wirst Dich wundern, wie ich auf die Sleeps gekommen bin. Ich hatte zunächst an diesen drei Stellen MsgBox-Befehle gestellt. Und da ging es. Eigentlich haben die ja nichts anders bewirkt, als das Programm zu verzögern.
Noch eine andere Frage. Es gibt Foren, da bekommt man eine E-Mail, wenn eine neue Antwort eingetroffen ist. Kann man das hier auch einrichten. Was haben eigentlich die Abbonierten Themen für einen Zweck?
-
- Offizieller Beitrag
Ändere mal bei den beiden Aufrufen die Größe von: $width * $height nach: $width * $height - 1
-
Was mich wirklich wundert ist ein funktionierendes Script, wenn Sleeps/Msgboxen vor den Dllcalls (AssembleIt ruft ja auch den Dllcall auf) stehen.
Weiterhin wundert es mich, dass wohl sämtliche Beispiele funktionieren...
Hm, bitte mal DllStructcreate() durch _DllstructCreate64() ersetzen, damit wird explizit ein Align auf eine durch 16 teilbare Speicheradresse erzwungen.
Diese Funktion wurde in AssembleIt() integriert, weil AutoIt nicht immer (tadaaaa) in der Lage ist, "automatisch" zu alignen (der "align"-Parameter in der DllStructCreate funktioniert(e) definitiv nicht 100%ig, was dazu führt, dass NICHT aligned wurde, d.h. die Einsprungadressen/Structs nicht immer "voll" im Speicher stehen -> Zugriff auf geschützten Speicher ausserhalb der Struct -> Absturz) -
- Offizieller Beitrag
Ich weiß jetzt nicht, was Du da genau übergibst.
Aber "$width * $height" sieht nach Anzahl der Pixel auf dem Bildschirm aus. Wenn Du aber bis zu dem Wert zählst, dann ist das doch ein Überlauf?!
Beginn bei 0 und dann bis "$width * $height - 1" oder sehe ich das falsch? -
Breite * Höhe
100 * 100
10000
9999
....
3
2
1
EndeEs werden exakt 10000 Pixel gezählt.
//EDIT
Oscar, du hast Recht!
Es wird per [edi+ecx*4] (ecx ist in diesem Fall die Nummer des Pixels) die Adresse des Pixels berechnet!
Der ASM-Code zählt "von oben nach unten". Die oberste Adresse im BxH-Beispiel 100x100 Pixel ist eben NICHT 10000, sondern 9999 (da 0-9999)....shame on meBei Autoit-DllStructs muss man aufpassen, denn innerhalb von AutoIt werden die Structitems nicht von 0 bis Ende-1 gezählt, sondern von 1 bis Ende!
Code
Alles anzeigen#cs _numberofpixel use32 mov edi,[esp+4] ;pointer pixel mov ecx,[esp+8] ;number pixel BxH mov ebx,[esp+12] ;color pixel mov eax,0 ;counter pixel with color sub ecx,1 ;adresse letztes pixel anpassen _next: ;label: for ecx=numberpixel to 0 cmp ebx,[edi+ecx*4] ;is dword=color ? (4 Bytes per pixel) jne _no ;no, next Pixel add eax,1 ;yes, one more found _no: ;no pixel with color was found sub ecx,1 ;next pixel jae _next ;jump if above (>0) or equal(0) to label ret ;return, returns eax #ce
Kommentiert man die Zeile jne _no (jump if not equal) aus, dann wird als Ergebnis die Anzahl der berechneten Pixel ausgegeben... -
- Offizieller Beitrag
Ah, so funktioniert es einwandfrei!
Bei mir läuft das Script mit diesen Werten:
_AssembleIt2() Anzahl Pixel = 13861 Zeit [ms] = 2.507
DllCallAddress() Anzahl Pixel = 13861 Zeit [ms] = 1.283und das bei einer Auflösung von 1920 x 1200.
Die Werte sind doch recht beeindruckend. Ich werde mich wohl doch mal (wieder, zuletzt auf dem C64) mit Assembler beschäftigen müssen. -