Ich suche bitte den Fehler in dieser Demo , weil bei :
r = f(42)
print (r)
der Wert "5" rauskommt oder ein anderer Wert der hier drin steht : b'\x83\xc0\x05'
statt 42+5
Dann wird deine Neugierde sich auf das debuggen solcher Anwendungen ausdehnen müssen. Denn es wird nie so sein, dass du “einfach” Assembler schreiben können wirst, und den dann ausführen. Was hier kracht ist das CFFI, und das ist komplex, und will umfänglich verstanden sein, wenn man sowas machen will. Schmeiß also WinDBG an, und schau, was da so passiert.
Nachtrag: wenn das Ergebnis immer das immediate-Argument ist, dann muss folgerichtig eax 0 sein. Und warum das 0 und nicht 42 ist, liegt eben am CFFI, was durch ctypes genutzt wird.
Mehr als aus Neugier wird man das rein in Assembler ja sowieso nicht machen wollen. Das ist kompliziert und fehleranfällig, funktioniert so dann nur auf einer Plattform, also Windows *und* 32-Bit schränken das ein, und man wird sich der Einfachheit halber sowieso mit C beschäftigen müssen, denn das c in `ctypes` steht ja für C.
Werden bei der Windows, 32-Bit ABI Argumente überhaupt über Register übergeben? Wer muss den Stack aufräumen? Aufrufer oder Aufgerufener?
Ich wuerde das erstmal als via Stack uebertragen interpretieren.
Wenn man Assembler machen will, dann ist C oder C++ dafuer schlicht um Groessenordnungen besser geeignet. Weil das Tooling schon gleich dabei ist, ein Debugger dafuer kann immer auch Assembler darstellen, und man sieht ueberhaupt, was da passiert. Python ist da wirklich die schlechtmoeglichste Wahl.
AMD64 hat genug Register, dass man die meisten Parameter ohne Stack übergeben kann.
Ich habe kein Windows um das selbst testen zu können, sehe aber keinen offensichtlichen Fehler.
Das wäre dann wohl die 64 Bit ABI und da wird das erste int-Argument offenbar in ECX übergeben. Dann müsste der Code im ersten Beitrag aber richtig sein. Der Godbold-Code ist ja nicht optimiert, da wird erst ECX in den Stapelrahmen mit den lokalen Variablen geschrieben um den Wert danach gleich wieder von dort auszulesen. Optimiert macht der Compiler da was nettes und ”missbraucht” LEA für die Addition:
Warum kann man nicht die Variable in eax reinbringen mit : mov eax, ecx ?
Kann man irgendwie eine Adresse dort reinbringen von Python wo die Variable reingelegt wird?
Ich versteh das nicht , was da passiert.
Danke
Zuletzt geändert von funkheld am Samstag 21. Januar 2023, 19:28, insgesamt 1-mal geändert.
Noch Anmerkungen zu Deinem Code: ctypes kennt bereits memmove, das selbst zu definieren ist also nicht nötig.
Ich persönlich bevorzuge ein char-Array, weil das klarer und sicherer ist:
Oh , danke für die Info , ich habe 32bit Python 3.9.0
Wie kann man das Programm bitte anpassen, das 32bit-Variablen erkannt werden?
Oder muss ich das Python mit 64bit installieren?
Naja wenn die 64-Bit ABI funktioniert, wird das ein 64-Bit-Python gewesen sein. Und das erklärt dann natürlich auch warum das bei Dir nicht funktioniert. Bei der 32 ABI kommt das Argument tatsächlich über den Stack mit einem Versatz von 4 Bytes zum Stapelzeiger. Die Routine müsste also aus diesen Bytes bestehen: b"\x8b\x44\x24\x04\x83\xc0\x2a\xc3"
Jetzt funktioniert es mit Python 3.9.0 32bit
------------------------------------
b"\x8b\x44\x24\x04\x83\xc0\x2a\xc3"
-----------------------------------
Wie sieht das jetzt oben bitte mit Stack mit einem Versatz von 4 Bytes zum Stapelzeiger aus?
@funkheld: Die Argumente liegen auf dem Stack. Und als erstes liegen dort 4 Bytes Rückkehradresse vom CALL, darum der Versatz. Warum willst Du doch gleich noch mal Assembler verwenden wenn Du nicht weisst, wie man in Assembler Aufrufe mit Argumenten macht‽
@funkheld: Welches Buch denn? Das was ich von dem Autor als PDF gefunden habe nennt/behandelt drei Assembler (A86, MASM, TASM) ist aus den 90ern und behandelt soweit ich das sehe 16-Bit DOS Programmierung. Und warum überhaupt Assembler? Welches tatsächliche Problem denkst Du damit lösen zu können das man nicht in Python oder einer anderen Programmiersprache lösen kann? Eine Funktion die 5 oder 42 auf eine andere Zahl addiert ist es ja eher nicht, das geht mit Python einfacher als wenn man da versucht etwas in Maschinensprache zu schreiben, und das funktioniert dann auch auf allen Plattformen auf denen Python läuft, und nicht nur unter einem 32-Bit-x86 Python für Windows.