Assemblerfunktion zum Aufsummieren direkt in AutoIt

  • Diese Frage geht direkt an die (vielen) Assembler-Profis hier im Forum.
    Aktuell arbeite ich in den letzten Monaten an meinem bisher größten AutoIt-Projekt (werde ich im Laufe des Jahres noch veröffentlichen).
    Hierfür wäre es sehr schön, wenn ich eine Funktion hätte, welche sehr fix die Summe über ein Float- oder Double-Array im Speicher berechnet.
    Die Windows-API bietet so eine Funktionalität nicht und die anderen Möglichkeiten die ich habe, sind auch nur Workarounds die mir nicht so gefallen.

    Da ich weiß, dass hier viele fähige Assemblerköpfe im Forum herumlungern, wollte ich mal fragen ob jemand mir eine Funktion schreiben kann, welche den Code über Assembler realisiert und aus AutoIt heraus fix aufrufbar macht (gesehen habe ich soetwas hier schon - bin aber selbst völlig minderbemittelt bei dem Thema).
    Das Grundgerüst stelle ich mir hierfür folgendermaßen vor:

    Man bräuchte also ingesamt 4x Binärcode, da es ja insgesamt 4 Fälle gibt.
    Genial wäre natürlich auch die Nutzung von Vektorfunktionalitäten, wenn diese in älteren CPUs aucht unterstützt werden (soll ja große Kompatibilität haben).

    Wer weiß - vielleicht hat einer ja Lust mir entsprechend zu helfen.

  • Heyho!

    Wer weiß - vielleicht hat einer ja Lust mir entsprechend zu helfen.

    Aber sowas von!!!! Endlich habe ich mal Gelegenheit, mich für deine vielen genialen Posts und Scripte zu revanchieren:party:

    Ich geh mal in die Spur....

  • Da ich mich erst stundenlang in ASM einarbeiten muss, um eine simple Addition durchzuführen, lasse ich Andy den Vorrang, zumal das Ergebnis wesentlich besser sein dürfte, aber hier die DLL Version, falls Interesse besteht:

    Im Anhang die zwei DLLs.

    Die DLL habe ich in Freebasic geschrieben.


    Btw, wie soll bei der Float summiert werden, wenn du ein Double Array übergibst? Soll Float summiert werden oder Double? Das Ergebnis ist natürlich Float.

  • Naja,

    man könnte ja die dll, bzw deren Inhalte/Code mit entsprechendem Header versehen und in eine AutoIt-Funktion aka DllCallAddress() überführen.

    AspirinJunkie hat ja die "Kompatibilität" auch zu "älteren" Prozessoren angesprochen, ich werde "oldschool" x86 (8088)-Code schreiben, und, da es ja auch Leute mit "neueren" Prozessoren geben sollte, deren SSE- bzw. AVX-Fähigkeiten ansprechen. Es gibt dort Prozessorfunktionen um 4/8/16 floats/double in einem rutsch zu addieren. das bekommst du ohne C bzw. C++ "intrinsics" (welche auch nur die Prozessorfunktiopn wrappern) nicht hin.

  • Das ist der optimierte x64 ASM Output vom Compiler:


    x86:


    x64:

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (31. August 2024 um 16:08)

  • Hui und wie mache ich daraus einen in AutoIt verwendbaren Binärcode?

    wie soll bei der Float summiert werden, wenn du ein Double Array übergibst?

    Gar nicht. Wenn ich ein Float-array habe dann soll der Float-Code verwendet werden. Gemischt wird natürlich nicht.

    Ansonsten möchte ich ja eben keine Dlls dazulegen, sondern das bewusst intern im AutoIt-Code selbst mitliefern.

    Aber danke schonmal Jungs. Wusste doch, dass ich die Spezis damit anfixe.

  • Das ist der x64 ASM Output vom Compiler:

    Cool, bin nur drübergeflogen, aber wie das aussieht, ist der "clevere" Teil von dir geschrieben. Zeig mal bitte den Freebasic-code.

  • Cool, bin nur drübergeflogen, aber wie das aussieht, ist der "clevere" Teil von dir geschrieben. Zeig mal bitte den Freebasic-code.

    Den ASM Code hat der Compiler gebastelt - der FB Code ist simpel:

    Man kann auch die Optimierung ausschalten, damit mehr Kompatibilität ensteht, aber zugunsten der Geschwindigkeit.


    Hui und wie mache ich daraus einen in AutoIt verwendbaren Binärcode?

    Gar nicht. Wenn ich ein Float-array habe dann soll der Float-Code verwendet werden. Gemischt wird natürlich nicht.

    Ansonsten möchte ich ja eben keine Dlls dazulegen, sondern das bewusst intern im AutoIt-Code selbst mitliefern.

    Aber danke schonmal Jungs. Wusste doch, dass ich die Spezis damit anfixe.

    Ich muss mal checken, wie man aus dem Code ein Binär Code erstellt, sodass man ihn einfach per DLLCallAddress aufruft.

    Wie du in der Funktion SumF sehen kannst, ist innerhalb der Funktion die Variable fSum als Single (Float) definiert, d.h. die Summe ist anders als mit Double, deshalb meine Nachfrage.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (31. August 2024 um 18:08)

  • Hi, ich kenn mich mit Assembler in AutoIt nicht so gut aus, nutze aber im moment Rust gerne und dachte mir, dass die Sprache doch sehr optimiert sein soll.
    Mit den passenden Parametern hab ich das ganze auf 8KB (x86) / 9KB (x64) bekommen und die Funktionen sind in Assembly auch deutlich kürzer, als dass was ich bei UEZ bei Freebasic sehe.
    Weiß aber leider nicht, wie man das mit AutoIt ausführt und ob der Code so funktioniert :)

    x86:

    x64:

    Code:

    Cargo.toml (für die c-lib und die compiler einstellungen zur optimierung):


    Vielleicht hilft euch das ja weiter (und ich hatte etwas Spaß mit den Compileroptionen rumzuspielen :D)

  • sodele, hab da was....

    14 Zeilen ASM-Code aka 44 Bytes Code müssen für die Summierung der Floats reichen^^

    Problem ist, wie üblich bei Summierung von vielen Floats, die Ungenauigkeit. AutoIt lügt ja wie gedruckt, rechnet intern mit 64 Bit, da finden dann keine/kaum Überläufe statt aber der ASM-Code rechnet "nur" mit 32Bit pro Float

    Aktuell bin ich bei 0,7 Prozessortakten pro Addition....die Compiler optimieren sehr stark, machen loop unrolling und berücksichtigen cache-lines...mache ich alles nicht....:/

    AspirinJunkie , wie viele Floats müssen da zusammengezählt werden? Minimal und maximal? Ich würde dann den Code für X64 und Double anpassen.

    Die Summe von 1.000.000 Floats werden in ca. 0.3ms berechnet, sollten das mehr Additionen sein, würde ich mit einer Handvoll Zeilen mehr noch ggf. Faktor 2-3 an Geschwindigkeit rausholen können. Aktuell muss die Anzahl durch 4 teilbar sein (Struct ggf. mit Nullen auffüllen) wenn man gleichzeitig 16 Zahlen addiert (per AVX) , muss die Structgröße glatt durch 16 teilbar sein.

    Dazu MUSS die Struct 16-Byte-aligned sein, warum das nicht standardmäßig in DllStructCreate implementiert ist weiß wieder mal kein Mensch...Ich habe dazu eine Funktion gebastelt. Man könnte auch eine Bitmap erstellen, die ist immer 16-Byte aligned und an deren Adresse die Struct erstellen.....

    UEZ´s Compilercode liest übrigens unaligned aus dem Speicher...der S U P E R G A U !!8|


    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

    6 Mal editiert, zuletzt von Andy (31. August 2024 um 23:41)

  • Habe mir mal den Code von Rust angeschaut....da schiessen mir ehrlich gesagt die Tränen in die Augen...

    Der Prozessorbefehl, den alle Compilate (bisher) (und auch ich^^) benutzen um die Floats zusammenzuzählen lautet ADDPS

    image.png

    Wie man im Schaubild sieht, addiert der Befehl 4 Floats aus einem Register oder Speicher zu den 4 Floats im Register....DAS ist der Sinn und Zweck von SSE (Streaming SIMD Extensions), die parallele Ausführung von Instruktionen, hier die Addition. SIMD heißt Single Instruction Multiple Data, man kann MEHRERE Daten gleichzeitig bearbeiten.

    Ich in meinem ASM-Programm mache das auch so, ich lese 128 Bit (16 Byte) an Daten ein und addiere diese zu den 128 Bit Daten (aka 4 Floats = 16 Bytes) im Register....logischerweise muss man dann, um die nächsten 4 Floats (16 Bytes) zu addieren, im Speicher auch 16 Bytes weiter springen....Rust springt 4 Bytes weiter....addiert also immer nur EINE Float!!! Natürlich werden die folgenden 3 Floats auch zu den entsprechenden Teilen im Register dazuaddiert, das ist aber völlig irrelevant, da der Compiler diese Addition nie berücksichtigt!

    Die Rust-Schleife läuft also 4x länger als eigentlich vorgesehen, und bei 3 von 4 ADDPS haut auch noch der unaligned Speicherzugriff voll rein...Soviel zu "Compiler-Optionen".....:Face:

    UEZ´s Compiler benutzt für die Addition der Floats den uralten (seit 1999 überflüssigen) Coprozessor mit
    fadd qword ptr [ebx]

    und addiert, wie Rust, jede der Floats im Speicher nacheinander.....=O


    Könnte mal jemand BITTE einen GCC oder Intel/M$-Compiler anwerfen? Und damit mal versuchen, ob mit deren Compileroptionen diese simple SSE-Addition "richtig" ausgeführt wird?:Glaskugel:


    Und um jetzt die aufkommende Frage der interessierten Leser zu beantworten: "Ja, Andy, du hast jetzt im letzten Schleifendurchlauf alle Floats addiert, die bestehen im XMM-Register aber doch aus 4 einzelnen Floats die auch noch zusammengezählt werden müssen!"

    Ja, stimmt! Im XMM-Register stehen 4 Floats "hintereinander", um innerhalb eines XMM-Registers die einzelnen Teile zusammenzuaddieren, gibt es den image.png

    der addiert innerhalb des Registers.

    Angenommen im Register xmm0 stehen die Floats 1.0 2.0 6.0 7.0

    dann wird in der Instruktion HADDPS xmm0,xmm0 folgendes berechnet

    6.0 + 7.0 =13.0 geht ins 4. Registerteil

    1.0 + 2.0 = 3.0 geht ins 3. Registerteil

    6.0 +7.0 =13.0 geht ins 2. Registerteil

    1.0 + 2.0 = 3.0 geht ins 1. Registerteil

    Im Register xmm0 stehen also die Floats 13.0 3.0 13.0 3.0

    beim nochmaligen HADDPS xmm0,xmm0 wird berechnet

    13.0 + 3.0 =16.0 geht ins 4. Registerteil

    13.0 + 3.0 = 16.0 geht ins 3. Registerteil

    13.0 +3.0 =16.0 geht ins 2. Registerteil

    13.0 + 3.0 = 16.0 geht ins 1. Registerteil

    Danach stehen in allen Registerteilen (Floats) die Summe der 4 einzelnen Floats aka die Gesamtsumme aller Floats

    Tadaaaaaa!

    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 (31. August 2024 um 23:28)

  • Ich zitiere mich mal selbst:

    Könnte mal jemand BITTE einen GCC oder Intel/M$-Compiler anwerfen? Und damit mal versuchen, ob mit deren Compileroptionen diese simple SSE-Addition "richtig" ausgeführt wird? :Glaskugel:

    Habe eben auf https://godbolt.org mal folgende Funktion mit den verschiedensten Compilern durchgetestet.

    Code
    void sumArray(float* x,int* n) {
        int i;
        float sum;
        for (i = 0; i < n; i++) {
            sum += x[i];
        }
    }

    Bin ja nicht der C-Spezialist, sollte so aber passen....

    K E I N E R der von den zwölfundneunzig von mir ausgewählten Compilern hat etwas anderes gemacht, als nacheinander einzelne Floats zu addieren. Von SSE/SIMD oder anderen seit Jahrzehnten möglichen Techniken zur parallelen Berechnung keine Spur....

    Ich spiele mal mit den Compileroptionen rum....schaumamal

    //EDIT

    So wie ich das sehe, empfehlen die Compiler-Hersteller die Verwendung von Intrinsics...

    https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html

    Damit werden die ASM-Instruktionen in die Hochsprache gehievt...warum auch nicht, da macht der Compiler wenigstens (ohne zu "optimieren") was er soll!

    HADDPS https://www.intel.com/content/www/us…4&ssetechs=SSE3

    image.png

    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

    3 Mal editiert, zuletzt von Andy (1. September 2024 um 06:37)

  • Jetzt sind wir ja schon auf dem Level den ASM-Code zu optimieren.
    Der interessante Schritt dazwischen "ASM-Code in ein aus AutoIt heraus aufrufbares Binary zu überführen" sind wir aber bislang noch nicht angegangen.
    Hatte AssembleIt da nicht Techniken dafür?

    wie viele Floats müssen da zusammengezählt werden? Minimal und maximal? Ich würde dann den Code für X64 und Double anpassen.

    Komplett unterschiedlich: Von 2 bis 1 Million in Einerschritten alles möglich.

    Ansonsten versuche ich die Taktik zu fahren: Lass sie dir erstmal ihren kleinen Finger reichen und nimm dir dann die ganze Hand ;)
    Auch wenn ich die Summenfunktion ebenso gut gebrauchen kann, benötige ich sie im konkreten Fall für die Berechnung des Mittelwertes des jeweiligen Arrays.
    Wir können das, falls hier die Lust besteht - dann noch beliebig erweitern.
    Z.b. könnte man anstatt dem naiven Ansatz die Kahan-Summation implementieren um den numerischen Fehler so gering wie möglich zu halten.

    Um mal den Schleier fairerweise etwas zu lüften: Es geht um BLAS/LAPACK.
    Die haben interessanterweise tatsächlich keine Funktionalität zum Aufsummieren (nur für Absolutsummen), einfach weil das zu profan ist und die nicht glauben konnten, dass das jemand aus einer langsamen Programmiersprache heraus aufruft.
    Ganz ganz konkret benötige ich es gerade um die Mittelwerte der Spalten der Jacobimatrix zu berechnen, damit ich eine Total-Least-Squares-Lösung per Singulärwertzerlegung berechnen kann.
    Momentan behelfe ich mir, indem ich einfach das Skalarprodukt des Vektors mit dem Einheitsvektor berechne.
    Das geht zwar immer noch 1.000x schneller als nativ in AutoIt zu rechnen aber elegant ist es halt auch nicht.
    In einem nächsten Schritt könnte man die Schleifenvariablen per Parameter anpassbar machen, wie es bei BLAS so üblich ist.
    Dann könnte man z.B. auch direkt die Diagonalensumme einer Matrix berechnen ohne erst umzukopieren.
    Aber wie gesagt - das alles nur optional für vielleicht später mal.

    Bei aller Aufregung, sollten wir aber nicht vergessen,dass Al Bundy 1966 Vier Touchdowns in einem Spiel gemacht hat und den Polk High School Panthers damit zur Stadtmeisterschaft verholfen hat!

  • Der interessante Schritt dazwischen "ASM-Code in ein aus AutoIt heraus aufrufbares Binary zu überführen" sind wir aber bislang noch nicht angegangen.

    Doch, schau mal in mein Script in Post #10.

    Binärcode mit Aufruf per DllCallAddress()

    Komplett unterschiedlich: Von 2 bis 1 Million in Einerschritten alles möglich.

    Ok, dann wird es interessant. Ggf. macht es dann auch Sinn, den (für parallele Berechnungen) lahmarschigen Prozessor (CPU) mit Hilfe der Grafikkarte bzw. in die CPU integrierter GPU auf die Sprünge zu helfen.

    Matrixberechnungen werden nicht ohne Grund bei Supercomputeranwendungen auf GPU´s ausgelagert. Die sind dafür prädestiniert, Vektorisierungen sind dort einfach zu erstellen...Cuda ist auf Nvidia beschränkt, daher habe ich solches schon in AutoIt per OpenCL umgesetzt.

    Btw. Vektorisierung, UEZ und Kanashius das sollte man auch dem Compiler hinwerfen, dann macht der auch parallel ausführbaren Code...


    Hatte AssembleIt da nicht Techniken dafür?

    Na klar^^, habe imho sogar im letzten Jahr ein Howto verfasst...

    AssembleIt kann nun nach dem Testen/Debuggen selbstständig den AutoItcode mit Binärcode und Aufruf über DllCallAddress() erstellen, s.S. 7 unten

    How To _AssembleIt2() deutsch.pdf

    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. September 2024 um 10:15)

  • Doch, schau mal in mein Script in Post #10.

    Guck an - hatte das gar nicht für wahr genommen, da der ASM-Code ja nur in einem Comment steckte. Aber das ist ja wie ich nun sehe genau der Witz an AssembleIt2.

    Dein godbolt.org-Seite ist ja mal interessant.
    Ich habe zwar keine Ahnung von Assembler aber ein Träumchen wäre es, wenn ich dort den Code in C eingeben könnte und dann entweder direkt ein Binary oder ein ASM-Code erhalte, welchen ich in AssembleIt2 verwenden könnte,.
    Wäre das damit möglich und wenn ja: Wie müsste der C-Code hierfür strukturiert sein? Also wie müsste ich die Funktionsdefinition schreiben usw.

    Es kommt in meinem Fall ja auch nicht auf das theoretische letzte Prozent Performance an.

  • https://en.wikipedia.org/wiki/Kahan_summation_algorithm ist sehr interessant. Unten im Artikel ist von den optimierten sum()-Funktionen einiger Sprachen die Rede.

    Dann wäre es es echt eine Überlegung wert, den von diesen Compilern erstellten Code in eine AssembleIt-Funktion zu kopieren und den Binärcode erstellen zu lassen.

    Das wäre echt einfach....


    Ich habe zwar keine Ahnung von Assembler aber ein Träumchen wäre es, wenn ich dort den Code in C eingeben könnte und dann entweder direkt ein Binary oder ein ASM-Code erhalte, welchen ich in AssembleIt2 verwenden könnte,.

    Yepp, das funktioniert auch (fast) genau so

    image.png

    den Assemblercode (hier 64Bit) kannst du so ins AssembleIt einfügen, ich mach mal ein Beispiel.

    AssembleIt2_64 v 313.zip

    in Zeile 12 wurde das Register edi durch ecx ersetzt, s. 64-Bit Aufrufkonventionen, ggf. kann man das auch per fastcall o.ä. anpassen

    die DWORD PTR wurden durch DWORD ersetzt bzw. das PTR entfernt, das ist dem im AssembleIt verwendeten FASM Assembler geschuldet. Aber das erkennt AssembleIt und weist dich hin...

    Ansonsten könnte man die so erstellten bzw auch von UEZ und Kanashius erstellten Codes so einfügen und per AssembleIt testen und bearbeiten

  • Hm bei mir klappt es noch nicht ganz:

    In Zeile 12 wurde das Register edi durch ecx ersetzt, s. 64-Bit Aufrufkonventionen, ggf. kann man das auch per fastcall o.ä. anpassen

    Ok also ganz ohne Anpassungen kann ich den Output von denen also offensichtlich nicht verwenden?

  • Ok also ganz ohne Anpassungen kann ich den Output von denen also offensichtlich nicht verwenden?

    Jeder Compilerbauer kocht sein eigenes Süppchen. Würdest du bspw. den GCC-C-Compiler den Code erstellen/assemblieren lassen und per DllCallAddress im GCC aufrufen, dan würde das auch genau so funktionieren.

    Das macht dann ein Assembler / Disassembler, bspw. so , auch online

    image.png


    Bin heute Abend wieder Online, dann versuchen wir das mal ohne Modifikationen am Code....bis denne

  • Bin heute Abend wieder Online, dann versuchen wir das mal ohne Modifikationen am Code....bis denne

    Ok vielleicht hilft dir ja folgendes Skript ein bisschen:

    Damit kannst du direkt aus AutoIt heraus den ASM-Code und auch das Binary von dem godbolt-Server beziehen ohne erst auf deren Seite zu müssen.

    2 Mal editiert, zuletzt von AspirinJunkie (2. September 2024 um 07:40)

  • Ok vielleicht hilft dir ja folgendes Skript ein bisschen:

    Ui, DAS ist ja cool...

    Hm bei mir klappt es noch nicht ganz:

    Ja, Verständnisfehler oder von mir nicht richtig/exakt beschrieben:

    $bRet = _AssembleIt2("int", "square", "int", $a) aufgerufen mit dem Rückgabedatentyp, "Funktionsnamen" und den Parametern (Parameter wie beim DllCall, jeweils Datentyp und Variable) assembliert den ASM-Code, schreibt ihn in den Speicher, ruft ihn auf und gibt das Ergebnis der Funktion zurück. Der ASM-Code kann mit Debugger (aktuell nur für 32-Bitcode) nachvollzogen werden , Registerinhalte, Stack usw. Der aufgerufene (und assemblierte) ASM-Code läuft nativ auf dem Prozessor, der "Overhead" der _AssembleIt2-Funktion ist nur einige Millisekunden.

    _AssembleIt2("retbinary","Funktionsname") gibt den assemblierten Binärcode zurück, den man dann allerdings noch in eine Struct schreiben und aufrufen muss....Diese Funktion ist aktuell unnötig!

    Ich habe eine Erweiterung geschrieben, welche einige Zeilen AutoItcode erstellt, mit der dann der ASM-Code direkt per DllCallAddress() aufgerufen werden kann. Dazu werden die Parameter "retbinary",@ScriptlineNumber hinten an die Parameter von AssembleIt angehängt. Damit baut dann AssembleIt den kompletten Aufruf der ASM-binary aus dem Speicher, bsp:

    $bRet = _AssembleIt2("int", "square", "int", $a,"retbinary",@ScriptLineNumber)

    erzeugt (steht in der Scite Console und im Clipboard):

    Local $aStructMem = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", DllStructGetSize(DllStructCreate("byte[15]")), "dword", 4096, "dword", 64)
    Local $tCodeBuffer = DllStructCreate("byte[15]", Number($aStructMem[0])) ;Address aligned 64 and Memory is $MEM_COMMIT, $PAGE_EXECUTE_READWRITE
    DllStructSetData($tCodeBuffer, 1,"0x554889E5894DFC8B45FC0FAFC05DC3") ;write opcodes into memory
    $ret=DllCallAddress("int:cdecl", DllStructGetPtr($tCodeBuffer), "int", $a)

    und ersetzt dann

    $bRet = _AssembleIt2("int", "square", "int", $a)

    womit #include <assembleit2_64.au3> überflüssig wird


    Hier dein Beispiel (habe deine Fragen kommentiert/beantwortet)

    Noch etwas zum Verständnis:

    Im 64-Bit-Modus ist eine 64 Bytes aligned Speicheradresse zwingend notwendig, um die in den Speicher geschriebenen Opcodes auszuführen.

    DllStructcreate() richtet nur 4 Byte aligned aus, für den 32-Bit-Modus reicht das, bei 64-Bit-Modus nicht....daher der Umweg über VirtualAlloc. In AssembleIt gibt es eine Funktion _DllStructCreate64(), die exakt dafür vorgesehen ist. Im 32-Bit-Modus schadet das 64-Bit align auch nicht....gerade im Gegenteil, Zugriff auf aligned Daten führt idR zu schnellerem Code.

    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

    4 Mal editiert, zuletzt von Andy (2. September 2024 um 19:55)