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

  • RegEx

    • Andy
    • 26. Januar 2016 um 18:42

    Hallo Alina!

    Regexe für diverse Anwendungen findet man haufenweise im Internet! So viele, dass es schneller geht, diese durchzuprobieren als sich zu informieren für welche Engine sie geschrieben sind....

    Google mit "regex emailadresse" oder "regex telefonnummer" findet reichlich Treffer. Ich teste schnell hier : https://regex101.com

    Kopiere die Dateien per ctrl-c zusammen in eine Datei. Scite hat genug Platz, einfach als *TXT speichern und gut. Text-Datei einlesen und den Regex drüber laufen lassen sollte für dich ja kein Problem sein.

    Test:

    Code
    (((((((00|\+)49[ \-\/]?)|0)[1-9][0-9]{1,4})[ \-\/]?)|((((00|\+)49\()|\(0)[1-9][0-9]{1,4}\)[ \-\/]?))[0-9]{1,7}([ \-\/]?[0-9]{1,5})?)

    von hier http://regexlib.com/UserPatterns.aspx?authorid=ced08a7c-ab7c-415e-b575-81a3acc32e92&AspxAutoDetectCookieSupport=1
    funktioniert schon recht gut für Telefonnummern. Parameter für die Rückgabe der Gruppen im Array setzen! Oder die Gruppen im regex direkt rausschmeissen...

  • AutoIt und Arduino

    • Andy
    • 26. Januar 2016 um 13:24

    Viel "Kleinkram" mit nur einer Handvoll Ein/Ausgänge teste ich auf dem Arduino. Als "Prozessor" reicht aber meist ein Attiny45 oder 85. Der kostet nur knapp einen Euro und incl. aller anderen "Elektronik" passt das meist in eine Streichholzschachtel bzw. auf die Rückseite des 3er/4er-Batteriepacks.
    Den Attiny programmiere ich über den Arduino mit identischem Sketch s. HIER

  • iTalc Autologin

    • Andy
    • 25. Januar 2016 um 19:37

    Hi,
    Wenn du dir AutoIt bereits installiert hast, dann findest du im Scite - Menü "Extras" den AU3Recorder. Diesen Starten, die von dir gemachten Aufzeichnungen machen und dir dann das somit erstellte Script anschauen! Mit F5 kannst du es innerhalb von Scite ablaufen lassen oder auch zu einer EXE kompilieren wenn es funktioniert^^

  • Silentreader kommt aus der Deckung

    • Andy
    • 24. Januar 2016 um 20:23

    Hi,
    schön, dass es einen weiteren der "alten Säcke" hierher verschlagen hat :thumbup:
    Konstruktive Hilfe und Beiträge sind jedenfalls immer willkommen!
    Viel Spass weiterhin!

  • Assembler - Fortsetzung

    • Andy
    • 24. Januar 2016 um 19:18
    Zitat von DOheim

    Wo finde ich das Tutorial?

    Weniger ein Tutorial als ein Programmers Manual.

    Ist aber wie gesagt nur etwas für "Fortgeschrittene".
    Die Idee hinter AssembleIt ist ja, das gesamte Rumgezackere mit Fenstern, Speicher und Ein-Ausgabegedöns ,also alles, was in Assembler richtig Arbeit macht und fehleranfällig ist, von AutoIt machen zu lassen und in Assembler wirklich nur den benötigten "schnellen Inner Loop" in einer Handvoll Bytes umzusetzen.
    Egal um welches Problem es sich handelt, ist das mit einer Handvoll Befehlen zu erledigen. Kürzer/schneller geht aber IMMER! Das aber hinzubekommen "separates the boys from the men..." ;)


    Zitat von DOheim

    Nachdem ich in meinem Bitmap-Programm den entsprechenden Abschnitt ersetzt habe, werden statt 31 Sekunden nur noch 57 Millisekunden benötigt. Erfolg 1:500

    Das muss so sein! :thumbup:

  • ISN - war Scite - automatische Formatierung der Kommenatare auf Spalte 81

    • Andy
    • 23. Januar 2016 um 17:52

    AlignComment richtet Kommentare aus <--klick mich, ich bin ein Link!

    du musst nur die Zeile
    If $c_pos < 30 Then $c_pos = 30
    aus einkommentieren und die Spaltenposition des Kommentars an deine Bedürfnisse anpassen

  • Assembler - Fortsetzung

    • Andy
    • 22. Januar 2016 um 20:49

    Die XMM-Register 0 bis 7 sind erweiterte Register (128-Bit) und wurden mit dem "erweiterten" SSE/ SIMD (Single Instruction, Multiple Data)-Befehlssatz eingeführt,
    Damit kann man bspw. das XMM-Register je nach Befehl als 128Bit,2x64Bit, 4x32Bit, 8x16Bit oder 16x8Bit ansprechen und mit nur einem Befehl alle diese "Blöcke" im Register gleichzeitig bearbeiten. So ist es bspw möglich, 4 Pixel (4x32Bit) gleichzeitig zu verarbeiten! Oder 16 Bytes gleichzeitig uswusf...
    Sehr sehr fein :thumbup: , vor allem, weil die meisten Befehle nur 1-2 Prozessortakte benötigen!

    Ich habe in den Tutorials ein "altes" AMD-Papier mit der Befehlsreferenz (incl. Zeichnungen/Bildern!!!) verlinkt, etwas besseres habe ich bisher zu diesem Thema nicht gefunden.

    Achtung! Um mit diesen XMM-Registern zu kommunizieren, kann man NUR die SSE-Befehle verwenden, MOVD xmm1,eax schreibt den Inhalt des eax-Registers in die unteren 32Bit von xmm1 (entsprechend zurück mit MOVD eax,xmm1).
    Ich benutze das um ein paar Takte Speicherzugriff zu sparen statt PUSH/POP :rolleyes:
    Speicherzugriffe versuche ich wo es nur geht zu vermeiden, Wenn man mal Takte gezählt hat, wird man in dieser Beziehung etwas "eigenartig" :Face: Bekloppt ist man heutzutage bei der Verwendung von ASM sowieso :rolleyes:
    Ausserdem kann man in den 8 XMM-Registern 32 der "normalen" 32-Bit-Register zwischenspeichern, Register kann man nie genug haben 8o

    Natürlich kann man auch die XMM-Registerinhalte komplett oder teilweise in den Speicher (oder Speicher ins Register) schreiben. Mit SSE/SIMD-Befehlen ist der Befehlssatz im Prozessor um ca. das fünffache angestiegen, incl. einiger sehr schneller Befehle (1 Takt) um bspw. Registerinhalte zu addieren und danach zu multiplizieren...


    Ich stehe allerdings auf dem Standpunkt, dass man mit zwei Handvoll x86-ASM-Befehle JEDES programmiertechnische Problem erschlagen kann. Nur wenn man das Programm dann noch um Faktor x beschleunigen will, muss man tiefer in die Trickkiste greifen!

  • AutoIt und Arduino

    • Andy
    • 22. Januar 2016 um 20:02

    Hi,

    Arduino+AutoIt.zip

    Kopiere den kompletten Ordner "SerialEventAutoIt" in deine Arduino-Dateien (bei mir unter Benutzer/Arduino/blablub )
    Enthalten sind zwei Arduino-Sketche. Egal welchen dieser Sketche du in der Arduino-IDE lädst, der andere wird mitgeladen. Auf dem ersten Reiter "SerialEventAutoIt" findest du die Deklaration von Variablen für den Eventmodus und innerhalb des setup() die Initialisierungen für den seriellen Anschluß und die Reservierung für den String des Eventmodus.
    pinMode() bezeichnet den port für das Testprogramm im loop(), welches einfach nur eine LED an port 13 an- und ausschaltet (blinken).
    Der Sketch für den Eventmodus ist auf Reiter2 in der IDE editierbar, auf neuen Reitern kann man einfach bspw. Funktionen "auslagern".)

    Wenn du jetzt den Sketch auf den Arduino überträgst und startest, fängt die fest auf dem Arduino installierte (Debug-)LED an port 13 an zu blinken.
    Nimm jetzt irgendein analoges Bauteil (Fotodiode mit Vorwiderstand oder einfach nur einen Poti) und schließe dieses zwischen dem ANALOGEN port A3 und 5V an.
    Wenn du willst, kannst du an den digitalen ports 3 und 8 jeweils eine LED mit Vorwiderstand anschließen.
    Den analogen Wert des Bauteils an port 3 werden wir nun mit AutoIt auslesen, OHNE DEN SKETCH AUF DEM ARDUINO ZU ÄNDERN!
    Dazu das AutoItScript "blink.au3" starten.
    In der Console wird nun der Wert des analogen ports angezeigt, testweise die Fotodiode abdecken oder den Trimpoti ändern sollte man also in der Console nachvollziehen können.
    Wenn du die LED´s angeschlossen hast, kannst du die an port 3 nun mit den Tasten 1 und 0 nun ein- und ausschalten, bzw. die LED an port 8 blinken lassen. Man beachte das analogwrite() auf einen digitalen port 8, das ist das feine am Arduino, man kann diese ports als PWM-Signal ansteuern (quasi-analog von 0-255 also 0% bis 100% Spannung).

    Mit der Leertaste kannst du den DEBUG-Modus ein/ausschalten, dann werden alle Ein/Ausgaben an/vom Arduino in der AutoIt-console protokolliert.
    Viel Spass beim Rumexperimentieren :thumbup:

    Man sollte bei der Verwendung von eigenen Sketchen darauf achten, nicht unbedingt mit dem Eventmodus auf dem Arduino "in den Clinch" zu gehen. Beim experimentieren kann idR nichts kaputt gehen, ob aber alle eigenen Sketche in Verbindung mit der seriellen Verbindung des Eventmodus funktionieren, garantiere ich nicht :D

  • AutoIt und Arduino

    • Andy
    • 21. Januar 2016 um 21:57

    Hi,
    Ich habe mir einen Eventmodus auf dem Arduino geschrieben, welcher "hinter" dem eigentlichen Code läuft und über die serielle Schnittstelle mit AutoIt kommuniziert.
    D.h. während ein Sketch auf dem Arduino läuft und dort irgendwelche Daten an die Ports ausgibt oder einholt, kann ich von Autoit aus Daten an div. Ports senden oder von dort empfangen, quasi simultan.
    In extremo braucht man auch garkeinen lauffähigen Sketch auf dem Arduino zu schreiben, man kann auch alle Ports direkt von AutoIt aus steuern :o)

  • Assembler - Fortsetzung

    • Andy
    • 21. Januar 2016 um 17:32

    Ich sehe an deinem Code, du bist ( wieder?! ) mit dem ASM-Virus infiziert...das freut mich :party:
    Vielleicht hast du ja noch andere Scripte / Programm(teil)e, in denen man etwas beschleunigen könnte...immer her damit :thumbup:

  • Assembler - Fortsetzung

    • Andy
    • 20. Januar 2016 um 18:34

    Du machst nichts falsch, jedenfalls nicht wissentlich^^

    Das "Problem" sind die Variablen in deinem Code. Die Adressen dieser Variablen werden BEIM ASSEMBLIEREN (!!!!!) erstellt. Dazu ermittelt der Assembler anhand der ORG-Anweisung die ZUR ZEIT gültige Adresse des Assemblerprogramms im Speicher und addiert einfach die Bytes des Codes bis zu deiner Variable dazu.
    Beim nächsten Start des Programms sind aber völlig andere Adressen aktuell und es folgt ein Crash! Solange AssembleIt eingesetzt wird, ist das unerheblich, denn AssembleIt ermittelt die Startadresse per ORG $PTR_SOURCE_ASMCODE bei jedem Programmstart neu.

    Um das Problem zu umgehen gibt es mehrere Möglichkeiten:
    - Alle Variablen, Übergabeparameter, Rückgabewerte und was man sonst noch in und aus einem ASM-Programm verwenden will, schreibt man in eine Struct.
    Von dieser Struct muss man nur noch die Startadresse als einzige Variable an DllCallAddress() übergeben.
    Diese Variante wird bei größeren Projekten mit vielen Variablen bevorzugt.

    - Man reserviert sich einige Bytes vom Stack (SUB ESP,12) und kann nun per [ESP+0], [ESP+4], [ESP+8], diese 3 DWORDS benutzen. Nicht vergessen, den Stack nachher wieder per ADD ESP+12 wieder instandzusetzen. PUSH/POP innerhalb des Programms ist weiterhin verwendbar.

    -Man ermittelt die Startadresse des ASM-Programms im Speicher (die Adresse, welche bei ORG verwendet werden würde) und schreibt alle "Hartkodierten" Adressen NACH DEM ASSEMBLIEREN, ABER VOR AUSFÜHREN DES PROGRAMMS neu. Das ist das, was ein Compiler/Assembler macht, um bspw. EXE-Dateien zu erzeugen, welche ja bei jedem Start an einer anderen Adresse im Speicher geladen werden.. Relokation / relocation ist das Stichwort. Wenn ich irgendwann dafür Bedarf habe, werde ich das in AssembleIt() integrieren.


    Weiterhin ist mir aufgefallen, dass du die Bitmap-Dateien einfach einliest, die 54 Byte Header abschneidest und diese "Bitmapdaten" dann als Pixel weiterverwendest. So habe ich das früher auch gemacht :)
    Das funktioniert dann sauber, wenn man Einfluss auf die Erstellung der Bitmapdateien hat! Wenn irgendwelche Software verwendet wird und diese dann bspw. in der Bitmap noch Paletten verwendet, ist man in den Ar*** gekniffen ;) Vorsicht auch mit "Standardsoftware". Die ist nur so lange "Standard" wie der Hersteller das postuliert.
    Sicherer ist die Verwendung von _CreateNewBmp32FromFile(), damit hat man alle relevanten Parameter/Variablen.
    Sind die von dir verwendeten Bitmaps alle so klein, bzw. haben die nur wenige Farben?

  • Scripting.Dictionary sortieren

    • Andy
    • 18. Januar 2016 um 13:33
    Zitat von _pawa

    Ich habe leider nichts im Netz gefunden.

    Ich habe lt. google mit der Anfrage "scripting dictionary sort" ca. 340000 (dreihundertvierzigtausend) Treffer zum Thema gefunden, auf der ersten Seite mehrere VBA-Scripte, welche einfachst 1:1 nach AutoIt umzusetzen sind...

  • TCP Feedback

    • Andy
    • 16. Januar 2016 um 23:01

    Hi,
    hast du dir mal die hilfe zu TCPSend() angeschaut? Und dessen Parameter?

  • Assembler - Fortsetzung

    • Andy
    • 16. Januar 2016 um 16:56

    Das Prinzip ist einfach:
    Es wird eine Struct (UINT) mit allen möglichen Farben (256^3 0x000000 bis 0xFFFFFF) erstellt.
    In der ersten Schleife wird jede Pixelfarbe ausgelesen und deren Adresse in der o.g. Struct einfach um 1 erhöht.
    Letztendlich entsteht eine Liste mit mehr oder weniger "Nullen", da die meisten Farben garnicht verwendet werden.
    Also wird in der nächsten Schleife diese Liste durchlaufen, und jedes Mal, wenn ein DWORD ungleich Null gefunden wird, dann wird diese Adresse (die Farbe) in die entsprechende Hex-Darstellung umgeformt, ein Komma hinzugefügt, und anschließend die Anzahl (Integer) ebenfalls als ASCII-Ziffern in eine weitere Struct (Text) geschrieben. Linefeed dazu, fertig! Nächste Farbe...
    Ist dieser Text erstellt, aus der Struct auslesen, per stringreplace() das LF durch CRLF ersetzen und als "Abfall" erhält man die Anzahl der Farben.

    Die Verwendung von XMM-Registern rund um die Erstellung des Ziffernstrings ist dem Registerpressure geschuldet! Hätten sich die Jungs/Mädels bei der ersten Herstellung von 32-Bit-Prozessoren einige hundert (omg, was hätte das gekostet!!! ) Register gegönnt, dann würde es bis heute keinen 64-Bit-Modus geben...
    Und die Software wäre wesentlich schneller gewesen...

    Btw., bei der Mona-Lisa werden bei mir in 130ms die 145019 verschiedenen Farben gefunden und deren Häüfigkeit, incl. Texterstellung.

    Dateien

    mona-lisa.jpg 252,2 kB – 0 Downloads
  • Assembler - Fortsetzung

    • Andy
    • 16. Januar 2016 um 12:22

    Schau dir das mal an, hier hatte ich alle Pixelfarben einer Bitmap und ihre Anzahl per ASM ermittelt und diese direkt als String (RRGGBB,Anzahl) ausgegeben.
    Das funktioniert auch bei großen Bitmaps mit tausenden von verschiedenen Farben innerhalb von einigen hundert Millisekunden (jedenfalls auf meinem lahmen Rechner^^)

    In dieser Variante ohne AssembleIt aber incl. ASM-Sourcecode.

    C
    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    #include <StructureConstants.au3>
    #include <WindowsConstants.au3>
    ;~ #include <assembleit2_64.au3>
    
    
    
    
    #AutoIt3Wrapper_UseX64=n
    
    
    
    
    #cs _countpixelcolors           ;
        Use32                       ;32Bit!
    
    
        org $PTR_SOURCE_ASMCODE     ;only needed for assembleit debugger
    
    
        mov edi,dword[esp+4]        ;pointer bitmap
        mov ecx,dword[esp+8]        ;width bitmap
        mov ebx,dword[esp+12]       ;height bitmap
        mov esi,dword[esp+16]       ;pointer pixelstruct
        movd xmm1,dword[esp+20]     ;pointer textstruct
    
    
    
    
        rdtsc                       ;timer sichern
        push eax
    
    
        ;~ _asmdbg_()  ;debugger
    
    
        mov eax,ebx                 ;h
        mul ecx                     ;w*h
        mov edx,eax                 ;w*h
        movd xmm0, edx              ;sichern anzahl
    
    
        ;zuerst werden die Pixel durchlaufen, die Farbe jedes Pixels wird an der Speicherstelle seines "Farbwerts" hochgezählt
    
    
        @pixel_count:               ;alle pixel
        mov eax,[edi]               ;farbe
        and eax,0xFFFFFF            ;eliminieren alpha-channel
        ;~          _asmdbg_()
        inc dword [esi+eax*4]       ;farbwert=farbwert+1, address=colorRGB^^
        ;add dword [esi+eax*4],1         ;schneller?
        add edi,4                   ;nächste farbe
        sub edx,1                   ;pixelcounter
        jnz near @pixel_count       ;jump if not zero(<0)
    
    
    
    
        ;***********************************************************************************
        ;jetzt werden die gezählten Farbwerte nacheinander als Text in HEX-Darstellung und der Anzahl als Integerwert in eine textstruct geschrieben
        ;Format: 6BF1E5,1234567@crlf
    
    
        movd xmm4,edi               ;sichern pointer bitmap
    
    
        mov edx,0x1000000           ;anzahl farben 0xFFFFFF +1
        movd ebx,xmm1               ;pointer textstruct
        mov edi,-4                  ;pointer colorstruct
    
    
    
    
        @count_colors:
        sub edx,1                   ;jedes pixel
        jz @end                     ;alle pixel durchlaufen
        mov ecx,[esi+edx*4]         ;ecx=anzahl, edx=farbwert; esi=pointer pixelstruct
        cmp ecx,0
        je @count_colors            ;wenn ungleich null...ist farbe gefunden
    
    
        ;~     _asmdbg_()
    
    
    
    
        ;hex-werte farbe =6 Bytes
        ;aus den 6 nibbles die 6 bytes machen, nibble+48 (0x30) =ASCII-Ziffer
        ;zuerst aus den beiden bytes ( Bit 4444333322221111) die nibble erweitern zu 0000444400003333 und 0000222200001111
    
    
        movd xmm3,eax               ;sichern wg registerpressure
        movd xmm4,edx               ;aka push/pop
        movd xmm5,esi
        movd xmm6,ecx
    
    
        mov eax,edx
        mov edi,eax
    
    
        ;schneller ist natürlich eine LUT^^, aber so geht es auch
        ;**************************************************************
        mov edx,0                   ;6  nibbles
        _int2hex:
        mov ecx,20                  ;5*4 shiften
        lea esi,[4*edx]             ;anzahl der zu shiftenden bits
        sub ecx,esi                 ;ecx=20,ecx
        shr eax,cl                  ;nach al shiften
        and al,0xF                  ;obere 4 nibble eliminieren
        cmp al,9                    ;größer oder kleiner als A?
        jle _groesserA
        add al,7                    ;A-F
        _groesserA:
        add al,48                   ;1-9
    
    
        mov byte[ebx+edx],al        ;ascii-hexcode in struct
        mov eax,edi
    
    
        add edx,1
        ;    _asmdbg_()
        cmp edx,6                   ;alle 6 nibble bearbeitet?
        jne _int2hex
    
    
        add ebx,edx                 ;ein zeichen (6 bytes) weiter
        mov byte [ebx],44           ;komma
        add ebx,1                   ;ein zeichen weiter
    
    
        mov edi,ebx                 ;pointer text
        movd ebx,xmm6               ;anzahl integer
    
    
    
    
        ;************************************************************
        ;aus einer Zahl(Registerinhalt) einen ZiffernString machen: http://dcla.rkhb.de/umwandlung/int2dez.html
        ;und in die struct schreiben
    
    
        push   ebx                  ;alle benötigten Register sichern
        push   ecx                  ;alle benötigten Register sichern
        mov eax, ebx                ;Zahl laden
        mov ebx, 10                 ;Divisor
        xor ecx, ecx                ;ECX=0 (Anzahl der Ziffern)
        Schleife_1:
        xor edx, edx
        div ebx                     ; EDX:EAX / EBX = EAX Rest EDX
        push dx                     ; LIFO
        add cl,1                    ; ADD soll schneller sein als INC
        or  eax, eax                ; AX = 0?
        jnz Schleife_1              ; nein: nochmal
        Schleife_2:
        pop ax                      ; gepushte Ziffern zurückholen
        or al, 00110000b            ; Umwandlung in ASCII
        stosb                       ; Nur AL nach [EDI] (EDI ist ein Zeiger auf den String)
        loop Schleife_2             ; bis keine Ziffern mehr da sind
        mov byte [edi],0Dh          ;CR  CarriageReturn, man könnte auch ein Komma (ascii=2C) einsetzen, dazu noch ein nullbyte als EndOfString
        add edi,1                   ;ein Byte weiter
        pop   ecx                   ;Register wiederherstellen
        pop   ebx                   ;Register wiederherstellen
        ;************************************************************Ende Ziffer aus Register
    
    
    
    
        movd esi,xmm5
        movd edx,xmm4               ;restaurieren
        mov ebx,edi
    
    
        jmp @count_colors           ;schleife alle farben
    
    
    
    
        @end:
    
    
        ret
    
    
    #ce
    
    
    
    
    
    
    
    
    
    
    AutoItSetOption("GUIOnEventMode", 1) ;event mode
    
    
    _GDIPlus_Startup()              ;tt
    
    
    Global $ptr_bitmap, $hbmp, $iwidth, $iheight ;werden ByRef von _CreateNewBmp32FromFile ausgefüllt
    
    
    
    
    $sFile = FileOpenDialog("Bilder", @ScriptDir, "Bilder (*.jpg;*.bmp;*.png)")
    $DC_bitmap = _CreateNewBmp32FromFile($sFile, $ptr_bitmap, $hbmp, $iwidth, $iheight)
    
    
    ;assembled code by AssembleIt_64
    $binarycode = "0x8B7C24048B4C24088B5C240C8B742410660F6E4C24140F315089D8F7E189C2660F6EC28B0725FFFFFF00FF048683C70483EA010F85EAFFFFFF660F6EE7BA00000001660F7ECBBFFCFFFFFF83EA010F848C0000008B0C9683F90074EF660F6ED8660F6EE2660F6EEE660F6EF189D089C7BA00000000B9140000008D34950000000029F1D3E8240F3C097E020407043088041389F883C20183FA0675D901D3C6032C83C30189DF660F7EF3535189D8BB0A00000031C931D2F7F3665280C10109C075F366580C30AAE2F9C6070D83C701595B660F7EEE660F7EE289FBE96BFFFFFF5B0F3129D8C3"
    $tCodeBuffer = DllStructCreate("byte[" & StringLen($binarycode) / 2 - 1 & "]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1, $binarycode)
    
    
    
    
    $colorstruct = DllStructCreate("uint[" & 256 ^ 3 & "]");anzahl möglicher Farben
    $ptr_colorstruct = DllStructGetPtr($colorstruct)
    
    
    $textstruct = DllStructCreate("char[" & 18 * $iwidth * $iheight & "]");maximale Anzahl Zeichen
    $ptr_textstruct = DllStructGetPtr($textstruct)
    ;9 Stellen integer
    ;6 Stellen Hexdarstellung
    ;1 Stellen Komma
    ;2 Stellen CRLF
    
    
    $t = TimerInit()
    
    
    ;Pixelfarben zählen und in Hexcode,Anzahl umwandeln, schreiben in textstruct
    DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer), "ptr", $ptr_bitmap, "int_ptr", $iwidth, "int_ptr", $iheight, "int_ptr", $ptr_colorstruct, "int_ptr", $ptr_textstruct)
    ;~  $ret = _AssembleIt2("uint", "_countpixelcolors", "ptr", $ptr_bitmap, "int_ptr", $iWidth, "int_ptr", $iHeight, "int_ptr", $ptr_colorstruct, "int_ptr", $ptr_textstruct)
    ;~ ConsoleWrite('Takte: ' & $ret & @CRLF) ;### Debug Console
    
    
    ;in der dllstruct stehen nun die Farbe,Anzahl
    $text = DllStructGetData($textstruct, 1)
    $text = StringTrimRight($text, 1) ;letztes LF entfernen
    
    
    $m = TimerDiff($t)
    
    
    $text = StringReplace($text, @CR, @CRLF) ;autoit is fast too^^
    $number_colors = @extended + 1
    
    
    
    
    MsgBox(0, "Timer ASM picelcounter", "Within " & Int($m) & "ms " & $number_colors & " colors were counted!")
    
    
    ;anzeigen als text
    FileDelete("Pixelcounter.txt")
    FileWrite("Pixelcounter.txt", $text)
    ShellExecute("Pixelcounter.txt")
    
    
    $colorarray = StringSplit($text, @LF)
    _ArrayDisplay($colorarray)
    
    
    
    
    ;Autoit-Version, dauert.....sehr lange^^
    ;~ For $color = 1 To 256 ^ 3                         ;alle farben
    ;~     $anzahl = DllStructGetData($colorstruct, 1, $color);auslesen
    ;~     If $anzahl <> 0 Then ConsoleWrite(Hex($color - 1, 6) & @TAB & $anzahl & @CRLF)
    ;~ Next
    
    
    $hGUI = GUICreate("ASM Pixelcounter", $iwidth, $iheight);GUI
    $DC_gui = _WinAPI_GetDC($hGUI)  ;Device-context
    
    
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState()
    _WinAPI_BitBlt($DC_gui, 0, 0, $iwidth, $iheight, $DC_bitmap, 0, 0, 0xCC0020);bitmap in DC blitten
    
    
    Do
    Until Not Sleep(100)            ;
    
    
    
    
    
    
    
    
    
    
    Func _Exit()
    
    
        _GDIPlus_Shutdown()
        GUIDelete()
        Exit
    EndFunc                         ;==>_Exit
    
    
    
    
    Func _CreateNewBmp32FromFile($bmpfile, ByRef $ptr, ByRef $hbmp, ByRef $iwidth, ByRef $iheight) ;ptr to bitmapdata, it is possible to manipulate one pixel if needed
        Local $hbitmap, $hdc, $hcdc
    
    
        $hbitmap = _GDIPlus_ImageLoadFromFile($bmpfile)
        If @error Or $hbitmap = 0 Then
            MsgBox(0, "Func _CreateNewBmp32FromFile()", "Error opening File: " & @CRLF & $bmpfile)
            Return -1
        EndIf
        $hbmpfile = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
        $iwidth = _GDIPlus_ImageGetWidth($hbitmap)
        $iheight = _GDIPlus_ImageGetHeight($hbitmap)
        $hcdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hcdc, $hbmpfile) ;image im hcdc
    
    
        ;neue bitmap
        $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
    
    
        $hdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hdc, $hbmp) ;leere bitmap im hdc
        _WinAPI_BitBlt($hdc, 0, 0, $iwidth, $iheight, $hcdc, 0, 0, $srccopy);image in leere bitmap
        _WinAPI_DeleteDC($hcdc)
        _WinAPI_DeleteObject($hbmpfile)
        Return $hdc                 ;DC der Bitmap zurückgeben
    
    
    EndFunc                         ;==>_CreateNewBmp32FromFile
    Alles anzeigen
  • Assembler - Fortsetzung

    • Andy
    • 15. Januar 2016 um 13:28

    Wenn es um die Bearbeitung/Erstellung von Bitmaps geht, dann stelle dein Vorhaben/Idee hier im Forum vor, BEVOR du Stunden/Tage auf die Umsetzung verwendest. Es gibt hier einige Mitglieder, die bereits viel umgesetzt/programmiert haben. Mein eigener Fundus beschränkt sich auf etwa 100 ASM-Projekte, leider habe ich nicht mehr die Zeit mich intensiver mit der Materie zu beschäftigen...

  • Assembler - Fortsetzung

    • Andy
    • 14. Januar 2016 um 22:05

    Hi,
    bei Grafiken/Bitmaps brauchst du dich idR um garnichts kümmern!
    Es gibt diverse Funktionen, um an den Pointer auf die Pixeldaten einer Bitmap zu kommen.
    Ich habe die Funktionen _CreateNewBmp32() und _CreateNewBmp32FromFile() erstellt, weil sie im Vergleich zu anderen Methoden sehr schnell und flexibel sind!

    Um Grafiken selbst zu erstellen muss man eine leere (32-Bit BGRA-)Bitmap erstellen, und dann die Pixel einfach an die richtige Adresse reinschreiben.
    $HDC = _CreateNewBmp32($breite, $hoehe, $ptr, $hbmp) findest du in den Beispielen. Die Funktion arbeitet mit globalen Variablen $ptr und $hbmp, den ptr=Pointer erhält man somit, mit dem hbmp kann man die GDI-Funktionen bedienen. Der RückgabeParameter $HDC ist das Handle zum Device-Context DC, diesen benötigt man, um die "schnellen" BitBlt-Funktionen verwenden zu können. Siehe Beispiele....

    Grafiken laden kann man mit _CreateNewBmp32FromFile(). Identisches Procedere.
    Um sog. Backbuffer für bewegte, flimmerfreie (!) Grafiken zu erstellen kann man diese Funktionen natürlich auch nutzen!

    Beispiel, um Bild in Graustufen zu verwandeln, der Kommentar für den ASM-Code ist in englisch, da ich dieses Script im engl. Forum gepostet hatte.
    Im Prinzip geht es darum, den R, G, undB-Anteil des Pixels zusammenzuzählen und das Ergebnis durch 3 zu teilen. Somit erhält man einen Durchschnitt, diesen auf R,G und B geschrieben den entsprechenden Grauton.
    Da ein DIV in Assembler so ziemlich die "teuerste" Möglichkeit ist, durch einen Wert zu teilen, habe ich die wesentlich schnellere Variante gewählt 8o
    Man schreibt ja keine Assemblerscripte, um dann mehrere hunderttausend Prozessortakte zu verschwenden :party:

    AutoIt
    #include <AssembleIt2_64.au3>
    #include <GDIPlus.au3>
    
    
    #AutoIt3Wrapper_UseX64=n
    ;32Bit only!
    
    
    #cs _grayscale
        use32                                 ;32Bit!
    
    
        mov esi,dword[esp+4]                  ;Startadress Bitmapdata (Pixel)
        mov ecx,dword[esp+8]                  ;number of Pixel
        mov edi,21845                         ;konstant, *21845/2^16 is approximately 1/3 (replaces the slow DIV 3)
    
    
        _loop1:                               ;until ecx=0
        mov edx,[esi]                         ;load pixel  AARRGGBB  (RR+GG+BB)/3 = colour grayscale
        mov al,dl                             ;lowbyte (BB) Pixel to lowbyte al
        movzx bx,dh                           ;highbyte (GG) Pixel to lowbyte of bx (bh is 0)
        shr edx,8                             ;shift RR into dh
        add ax,bx                             ;BB + GG
        movzx bx,dh                           ;highbyte (RR) Pixel to lowbyte of bx (bh ist 0)
        add ax,bx                             ;and add: dx=RR+GG+BB
        mul edi                               ;ax=ax*21845      *21845/2^16 is about 1/3
        shr eax,16                            ;ax=ax/2^16   in al is now the greyscale colour for RR, GG und BB
        movzx dx,al                           ;grayscale to dl,  dh = 0
        shl edx,16                            ;grayscale to RR,  AA = 0!
        mov dh,al                             ;grayscale to GG
        mov dl,al                             ;grayscale to BB     edx is now 00alalal = grayscale AARRGGBB
        mov [esi],edx                         ;write pixel
    
    
        add esi,4                             ;address next pixel: 4 Byte = 1 dword = 1 Pixel
        sub ecx,1                             ;counter (next pixel)
        ja _loop1                             ;until ecx=0
        ;upper 3 lines are faster than loop _loop1            ;until ecx=0
        ret                                   ;return
    #ce                                        ;==>_grayscale
    
    
    
    
    $file = FileOpenDialog("Select 32 Bpp image!", @ScriptDir, "Image (*.jpg;*.bmp;*.png)", 1 + 2)
    if @error then exit
    
    
    _GDIPlus_Startup()
    
    
    Global $ptr, $hbmp, $iwidth, $iheight ;werden ByRef von _CreateNewBmp32FromFile ausgefüllt
    $DC = _CreateNewBmp32FromFile($file, $ptr, $hbmp, $iwidth, $iheight)
    
    
    ;pointer und bitmapgröße, mehr braucht man zum bearbeiten einer bitmap nicht!
    $ret=_AssembleIt2("handle","_grayscale","ptr", $ptr, "int", $iWidth * $iHeight)
    
    
    ;grafik speichern
     $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hbmp)
    _GDIPlus_ImageSaveToFile($hImage, @ScriptDir & "\greyscale.jpg")
    _GDIPlus_Shutdown()
    
    
    ShellExecute(@ScriptDir & "\greyscale.jpg")
    
    
    
    
    Exit
    
    
    
    
    
    
    
    
    
    
    Func _CreateNewBmp32FromFile($bmpfile, ByRef $ptr, ByRef $hbmp, ByRef $iwidth, ByRef $iheight) ;ptr to bitmapdata, it is possible to manipulate one pixel if needed
        Local $hbitmap, $hdc, $hcdc
    
    
        $hbitmap = _GDIPlus_ImageLoadFromFile($bmpfile)
        If @error Or $hbitmap = 0 Then
            MsgBox(0, "Func _CreateNewBmp32FromFile()", "Error opening File: " & @CRLF & $bmpfile)
            Return -1
        EndIf
        $hbmpfile = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
        $iwidth = _GDIPlus_ImageGetWidth($hbitmap)
        $iheight = _GDIPlus_ImageGetHeight($hbitmap)
        $hcdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hcdc, $hbmpfile)           ;image im hcdc
    
    
        ;neue bitmap
        $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
    
    
        $hdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hdc, $hbmp)                ;leere bitmap im hdc
        _WinAPI_BitBlt($hdc, 0, 0, $iwidth, $iheight, $hcdc, 0, 0, $srccopy);image in leere bitmap
        _WinAPI_DeleteDC($hcdc)
        _WinAPI_DeleteObject($hbmpfile)
        Return $hdc                                      ;DC der Bitmap zurückgeben
    
    
    EndFunc                                              ;==>_CreateNewBmp32FromFile
    Alles anzeigen


    Btw muss man sich bei Bitmaps auch nicht ums alignen kümmern, Bitmaps werden glücklicherweise an 16-Bytegrenzen aligned^^

    Also ideal, um auch Hardcore SSE/SIMD-Programme zu schreiben /* malzueukalyptusrüberwinkt */


    Zitat von DOheim

    Wie kann ich in meinem Assemblerprogramm einen zusammenhängenden Speicherbereich bestimmter Größe reservieren?

    Das macht man günstigstenfalls per dllstructcreate(). Da in dieser Funktion aber das alignen nicht zuverlässig funktioniert (hatte?), habe ich dort auch eine Funktion _dllstructcreate64() geschrieben, die braucht man ohnehin, um aligned Speicher in 64_Bitanwendungen zu reservieren.
    Diese Funktion ist in AssembleIt2_64 enthalten, einfach so benutzen wie dllstructcreate()

    Bei 32-Bitanwendungen ist idR kein alignment nötig, man kann also "normalerweise" dllstructcreate() verwenden.

  • Assembler - Fortsetzung

    • Andy
    • 13. Januar 2016 um 20:05
    Zitat von DOheim

    Am besten wäre es meines Erachtens, wenn man die Adresse des Strings ermittel könnte und diese dann dem Assemblerprogramm zur
    Verfügung stellen könnte. Aber wie ermittle ich die Adresse eines Strings?

    Die Adresse übergibst du, indem du an den Typ (int,str,byte usw.) ein * anhängst, also "str*" oder "int*".

    AutoIt behandelt Strings bei der Ausgabe/Anzeige genau wie C/C++ (logisch, deren API-Funktionen werden benutzt...).
    Daher sollte man, wenn man Strings mit enthaltenen Nullbytes benutzt, diesen an eine Struct übergeben.
    Die Frage ist, wo Strings mit enthaltenen Nullbytes herkommen, deren Vorkommen in der freien Wildbahn ist SEHR begrenzt! IdR. sind das sowieso BYTE Structs, daher sollte man diese auch so behandeln!

    Weiterhin musst du die "Endianess" (<-klick mich, ich bin ein Link) beachten, das bringt die meisten Assemblerjünger (und meist auch die Cracks) zur schieren Verzweiflung.
    Bsp.: Im Speicher stehen nebeneinander die Bytes ABCD.
    Liest man die BYTES nacheinander aus, dann erhält man als Lowbyte bspw eines Registers (also BL von EAX) erst A, dann B, dann C, dann D
    Liest man ein DWORD (egal welchen Typs) aus, dann erhält man im Register EAX die Bytereihenfolge DCBA....viel Spass^^


    AutoIt
    #include <assembleit2_64.au3>
    #cs _numberofpixel
        use32
        org $PTR_SOURCE_ASMCODE                                    ;only needed for assembleit debugger
        mov edi,[esp+4]                                            ;pointer
        mov ecx,[esp+8]                                            ;anzahl
    	mov edx,0;in dl steht das byte
        _ASMDBG_()                                                 ;debug-gui anzeigen
        mov eax,0
        _next:
        mov ebx,[edi+eax]                                          ;4 Bytes von adresse lesen, little endian aus ABCD wird DCBA!!!!
        mov edx,0
        mov dl,byte[edi+eax]                                       ;1 Byte von adresse lesen
        _ASMDBG_()                                                 ;debug-gui anzeigen
        add eax,1                                                  ;next pixel
        cmp eax,ecx
        jne _next
        ret                                                        ;return, returns eax
    #ce
    ; $string="1234567890"
    $string = "123" & Chr(0) & "4567890"
    $len = StringLen($string)
    $string_pointer_struct = DllStructCreate("char[" & $len & "]") ;char-struct erstellen, die kann man auf einen rutsch mit dem string füllen
    DllStructSetData($string_pointer_struct, 1, $string)           ;alle "Buchstaben" in die struct schreiben
    $string_pointer_struct_pointer = DllStructGetPtr($string_pointer_struct) ;pointer auf die struct
    Local $ret = _AssembleIt2("uint", "_numberofpixel", "ptr", $string_pointer_struct_pointer, "int", $len)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    MsgBox(0, 0, "Beispiel Bytes")
    $bytes = "0x1122330044556677889900"                            ;bytes kann man schöner sehen^^
    $len = StringLen($bytes) / 2 - 1
    $bytes_pointer_struct = DllStructCreate("byte[" & $len & "]")  ;char-struct erstellen, die kann man auf einen rutsch mit dem string füllen
    DllStructSetData($bytes_pointer_struct, 1, $bytes)             ;alle "Buchstaben" in die struct schreiben
    $bytes_pointer_struct_pointer = DllStructGetPtr($bytes_pointer_struct) ;pointer auf die struct
    Local $ret = _AssembleIt2("uint", "_numberofpixel", "ptr", $bytes_pointer_struct_pointer, "int", $len)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    Alles anzeigen
    Zitat von DOheim

    Wenn das Assemblerprogramm als Ergebnis ein Feld erarbeitet, wie kann ich das dem aufrufenden Autoit-Programm zur Verfügung stellen?

    Am besten, indem du eine Struct erstellst und dann ausliest. An den Autoitcode gibst du den Pointer zurück!

    AutoIt
    #include <assembleit2_64.au3>
    
    
    #cs _numberofpixel
        use32
        org $PTR_SOURCE_ASMCODE                                               ;only needed for assembleit debugger
    
    
        mov eax,[esp+4]                                                       ;pointer auf den string
    
    
        ;   _ASMDBG_()                                                 ;debug-gui anzeigen
        mov dword[eax+0],"Hall"
        mov dword[eax+4],"o Au"
        mov dword[eax+8],"toIt"
        mov dword[eax+12],0                                                   ;nullbytes
    
    
    
    
        ret                                                                   ;return, returns eax
    #ce
    
    
    
    
    $string = "1234123412341234"
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $string = ' & $string & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    
    
    
    
    Local $pointer = _AssembleIt2("uint", "_numberofpixel", "str*", $string)  ;string an asm übergeben
    
    
    ;wir bekommen einen Pointer zurück
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $pointer = ' & $pointer & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    ;und den Pointer verwenden wir in Autoit
    $text_struct = DllStructCreate("char[13]", $pointer)                      ;eine struct im Speicher an der position des Pointers erstellen
    $text = DllStructGetData($text_struct, 1)                                 ;text kann man am Stück auslesen, das nullbyte markiert das stringende
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $text = ' & $text & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    ;jetzt wirds spannend!
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $string = ' & $string & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ;Autoit ist ein Interpreter, die Variableninhalte werden zwischengepuffert!
    
    
    
    
    ;Man kann aber auch direkt den text zurückgeben lassen, Rückgabetyp beachten!!!
    Local $text_aus_ASM = _AssembleIt2("str", "_numberofpixel", "str*", $string)  ;string an asm übergeben
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $text_aus_ASM = ' & $text_aus_ASM & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    Alles anzeigen
  • Func innerhalb Func möglich?

    • Andy
    • 12. Januar 2016 um 18:42

    https://autoit.de/onlinehilfe/intro/lang_datatypes.htm
    ergänzend dazu, weil´s zum Thema passt:
    https://autoit.de/onlinehilfe/keywords/Static.htm

  • Laufzeit Dienststatusabfrage

    • Andy
    • 9. Januar 2016 um 15:50

    Ergebnis: CMD True t=0.405 s WMI True t=0.398 s
    Ergebnis: CMD True t=0.384 s WMI True t=0.342 s
    Ergebnis: CMD True t=0.380 s WMI True t=0.354 s
    Ergebnis: CMD True t=0.379 s WMI True t=0.383 s
    Ergebnis: CMD True t=0.405 s WMI True t=0.391 s

    interessant, Win10 Tablet mit Prozessor Intel(R) Atom(TM) CPU Z3735F @ 1.33GHz, 1329 MHz, 4 Kern(e), 4 logische(r) Prozessor(en)
    CMD schneller als mein Laptop mit doppeltem Takt! Dafür WMI-Zugriff aber nur halb so schnell bzgl. Takt LaptopCPU
    Wie es aussieht, ist Intel bei WMI im Vorteil^^

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™