Assembler: Farben zählen

  • Im Thema RE: Assembler - Fortsetzung

    unter Beitrag #8

    hatte Andy diese Programm erarbeitet:

    Es fertigt eine Staistik über alle in einer Bitmap-Datei vorkommenden Farben an.

    Hier eine kleine Beispieldatei: rot1.bmp

    In dem Programm ist ein fertiger $binarycode eingefügt (Zeile216) , der von der Fuktion DllCallAddress aufgerufen wird. Das klappt auch einwandfrei und die Statistik wird angezeigt.

    Wird der $binarycode jedoch neu erzeugt, so funktioniert es nicht. Am besten kann man das bewerkstelligen, indem man unter der Zeile216 : $binarycode = "0x8B7C24048B4C240.....

    die beiden Befehle

    $binarycode = _AssembleIt2("retbinary", "_countpixelcolors")
    MsgBox(0,"",$binarycode)

    einfügt Der dabei entstehned $binarycode unterscheiden sich von dem in Zeile216 eingetragenen hinten um die letzten Bytes.

    Wo steck der Fehler?
    Vielen Dank schon einmal für eine Antwort!

  • Hi,

    da sind in deinem asm-code wohl einige Zeilen verloren gegangen :o)

    @end:
    pop ebx
    rdtsc
    sub eax,ebx

    ret

    Füge die 3 Zeilen zwischen dem @end: und ret dazu und alles läuft...

    Nur zur Erklärung, ich nutze zum "Takte zählen" den (bzw. einen der) Prozessorinternen TimeStampCounter, also einen Timer. RDTSC aka ReaDTimeStampCounter

    Der schreibt den aktuellen timestamp als 64 Bit "Timer" in die Register EAX und EDX. Ich nutze für kurze Schleifen nur die unteren 32Bit, also das EAX-Register.

    Dieses wird am Anfang des Codes auf den Stack gepushed, am Ende des Codes wird durch RDTSC wieder der neue Timestamp ausgelesen.

    POP EBX holt den alten Wert vom Stack

    RDTSC schreibt den aktuellen Timerwert in EAX, Info dazu https://www.felixcloutier.com/x86/rdtsc übrigens ein feines Nachschlagewerk..

    SUB EAX,EBX ermittelt die Differenz, also die Anzahl der Prozessortakte, in EAX

    Nach dem RET wird EAX an das aufrufende Programm, also AutoIt, zurückgegeben und kann angezeigt werden. Das macht übrigens der erste Parameter, das "uint" in AssembleIt. Beim DllCalladdress() werden der Rückgabewert und die Aufrufparameter in einem Array zurückgegeben.


    Übrigens, wenn Du Interesse hast, ich hatte im letzten Jahr AssembleIt noch etwas weiter aufgebohrt und etliches gefixt.

    Jetzt gibt es auch ein rudimentäres "How to", schau mal rein und sag mal was du davon hälst...

    AssembleIt2_64 v 313.zip

    In den Dateien Example1 bis Example 5 wird haarklein erklärt welche Möglickeiten AssembleIt hat, eins der "neuen" Features ist bspw. durch Anhängen von

    ,"retbinary",@ScriptlineNumber) an den Funktionsaufruf von AssembleIt2 wird der Aufrufcode für DllCallAddress() als einige Zeilen Code generiert und in die Konsole und ins Clipboard geschrieben, hier mal als Beispiel:

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (24. März 2024 um 13:16)

  • Hallo Andy,

    VielenDank für Deine Antwort.

    Ich hatte ja damals den $binarycode aus deinem Programm in mein Bitmapprogramm mit großem Erfolg eingebaut. Die Rechenzeit hatte sich um den Faktor 500 verkürzt.

    Aber ein Mangel bestand noch, dass die schwarzen Pixel (also Farbwert 0x000000) nicht erkannt wurden. Der Sache möchte ich nun auf den Grund gehen.

    Vielen Dank für die neue Variante von AssembleIt2_64 v 313.zip. ZurZeit arbeite ich mit der von dir unter

    <RE: AssembleIt2_64 incl. Debugger uvm...>

    veröffentlichten Variante.

  • Aber ein Mangel bestand noch, dass die schwarzen Pixel (also Farbwert 0x000000) nicht erkannt wurden.

    Hmmmm....DAS muss ich auch untersuchen....schön, wenn man Code dokumentiert...habs sofort gefunden :o)

    Code
        @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

    ich hatte schon bei Farbe = 0x000001 aufgehört, lass mal das jz @end weg und

    ersetze das Ende der Schleife mit

    Code
    	cmp edx,0					;ende erreicht?
        jne @count_colors           ;nein, dann weiter mit schleife alle farben

    Das müsste es gewesen sein....teste mal bitte und gib Rückmeldung :party:

    **EDIT

    besser das gesamte Script:

  • Total gut !!!!!!!!!!!!

    Wie schnell du das gefunden hast. Mit 89 ist man eben etwas langsamer.

    Ganz bequem übernehme ich nun meinem inneren Schweinehund gahorchend den Binarycode so wie er ist in mein Bitmap-Programm.

    Ich habe ja noch ein eigentlich einfaches Bitmap-Problem. Das verrate ich dir aber nicht. Sonst hast du es im Nu gelöst und ich lerne nichts hinzu :) . Wenn ich es aber dann gelöst habe, werde ich es in dir in diesem Thema miteilen. Wie ich dir damals schon gesagt hatte, habe ich Jahrzehnte Assembler programmiert. Aber es waren ja viel einfacher Rechner. Das hat heute ganz andere Dimensionen und das "Handwerkszeug" ist doch erheblich umfangreicher geworden. Jetzt habe ich mir erst einmal ein Rahmenprogramm geschrieben, das es mir beim Test leicht macht, zwischen den einzelnen Arbeitsphasen

    _AssembleIt2("uint ..." ,

    _AssembleIt2("retbinary ... " ,

    nur DllCallAddress("uint:cdecl ... " ohne _AssembleIt

    umzuschalten.

    Recht vielen Dank für deine Mühe!

    Gruß DOheim

  • Ich habe ja noch ein eigentlich einfaches Bitmap-Problem. Das verrate ich dir aber nicht. Sonst hast du es im Nu gelöst und ich lerne nichts hinzu :)

    Nanana....ich tüftele auch gerne, aber manchmal ist der Weg das Ziel! Mit dem "Weg" meine ich den gegenseitigen Austausch! Wie du sicher weißt, sind schon etliche der "anderen" Dinosaurier ausgestorben. Daher freue ich mich immer wie ein kleines Kind, wenn jemand an diesem "Oldschool Assembler Gedöns" auch (noch) seinen Spass hat.

    Wobei, um ehrlich zu sein, ich bemitleide ehrlich gesagt diese armen Schweine, die heute vor der Glotze sitzen und in irgendwelchen "neumodischen" esoterischen Sprachen sog. "Hightech" verzapfen und dann, wenn etwas nicht funktioniert, das Internet mit Hilfeanfragen fluten. Seltsamerweise sind dann die "Helfer" (fast) immer irgendwelche "alten Säcke", die sich (natürlich) sowohl mit dem altmodischen Kram aus dem Computerpleistozän auskennen, als auch mit dem neumodischen Gedöns:party:.

    Obwohl auch junge Leute unglaublich fit sind. Ich bekomme netterweise immer mal wieder Berichte aus Jülich vom dortigen Forschungszentrum und HPC (High-Performance-Computing) zugespielt und war auch schon dort und konnte mich mit einigen der "richtigen" Programmierer dort unterhalten. Da weiß jeder, wie er(sie) die Maschine codetechnisch zu füttern hat! Und ja, dort werden auch die letzten Register in den zig-tausenden Prozessoren ausgenutzt, um das letzte Quentchen Leistung rauszukitzeln. Ohne UMFASSENDE Assemblerkentnisse bzw. detailliertes Know-How über die internen Rechnerstrukturen ist auch keine "High-Performance" zu erzielen.


    Jetzt habe ich mir erst einmal ein Rahmenprogramm geschrieben, das es mir beim Test leicht macht, zwischen den einzelnen Arbeitsphasen

    _AssembleIt2("uint ..." ,

    _AssembleIt2("retbinary ... " ,

    nur DllCallAddress("uint:cdecl ... " ohne _AssembleIt

    umzuschalten.

    :party:.....würdest du dieses "Rahmenprogramm" ggf. mit uns anderen "Dinosauriern" teilen oder wenigstens kurz beschreiben was es macht?!:Glaskugel:


    Zitat

    Zitat von UEZ

    Echt jetzt? 8|

    Ja, ja - er ist der letzte Zeitzeuge der Schlacht von Waterloo. 😝

    =O.....du Sack8o...jetzt fühl ich mich alt.....:theke:...obwohl ich mich vor ner Stunde erst für 45min an meinen Klimmzugturm zum Schwitzen gebracht hatte....Calisthenics FTW!

  • Etwas off-topic, verzeiht mir, doch ich muss kurz meine Begeisterung zum Ausdruck bringen:

    ...obwohl ich mich vor ner Stunde erst für 45min an meinen Klimmzugturm zum Schwitzen gebracht hatte....Calisthenics FTW!

    Wenn dies dein Ernst war Andy => Calisthenics => Hut ab 👍 !

    Mit 89 ist man eben etwas langsamer.

    Falls dem so ist DOheim , wünsche ich dir weiterhin stetige Gesundheit 😇 .
    Freut mich das du noch so fit bist was etwaige Entwicklungstätigkeiten angeht - dies erhoffe ich mir für mich auch, doch wer weiß schon was das Leben so bringt.

    ==> end of off-topic

    Viele Grüße
    Sven

  • Vielen Dank für eure netten Antworten.

    Ich habe an meinem Rahmenprogramm noch etwas „herumgeschneidert“ und hoffe, dass es nun auch in fremder Umgebung funktioniert.

    Statt über $CmdLine die Phase einzustellen, ist es einfacher den Wert in Zeile 22 einzutragen.

    Protokoll() ist mein Autoit-Debugger. Bitte nicht daran stören.


    Ich habe noch eine Frage:

    Wäre es möglich, im Assemblerprogramm den Debugger-Aufruf z.B. so zu gestalten

    Stelle3) _asmdbg_()

    und dann im Debugger-Fenster die Zeichenfolge Stelle3 anzuzeigen? Das würde ungemein helfen.


    Hier mein Rahmenprogramm:

    Einmal editiert, zuletzt von DOheim (30. März 2024 um 17:52)

  • Ich habe noch eine Frage:

    Wäre es möglich, im Assemblerprogramm den Debugger-Aufruf z.B. so zu gestalten

    Stelle3) _asmdbg_()

    und dann im Debugger-Fenster die Zeichenfolge Stelle3 anzuzeigen? Das würde ungemein helfen.

    Wenn du Scite als Editor verwendest, springt der Debugger in die Zeile im Script, in der sich der Debuggeraufruf aktuell befindet. Du siehst auch die blauen Klammern hinter _asmdbg_()

    Für das debuggen ist es also sehr hilfreich das Debuggerfenster so zu plazieren, dass der Scriptcode in Scite nicht verdeckt ist.

    Dann kannst du, wenn du im Debuggerfenster auf NEXT klickst, den Schritt zum nächsten _asmdbg_() mitverfolgen.

    Außerdem steht in der Kopfzeile des Debuggerfensters, in welcher Zeile in Scite sich der Debugger aktuell befindet

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (1. April 2024 um 06:34)