Ich versuche, eine Funktion in Assembly zu verwenden, die von einem C-Projekt aufgerufen wird. Diese Funktion soll beispielsweise eine libc-Funktion aufrufen printf()aber ich erhalte weiterhin einen Segmentierungsfehler.
In der .c-Datei habe ich die Deklaration der Funktion, sagen wir mal
“Irgendwelche Hinweise wären willkommen”: int *ptr;
– Saph
13. Januar 2011 um 3:55 Uhr
@Sapph +1 aber es hilft nicht :))
– Benutzer173973
13. Januar 2011 um 3:56 Uhr
@Sapph: Du meinst void*, Rechts?
– Benutzer541686
13. Januar 2011 um 4:04 Uhr
@Lambert: Es ist im Nachhinein so schmerzlich offensichtlich! Ich schäme mich. +1 für Sie, mein Herr.
– Saph
13. Januar 2011 um 4:42 Uhr
Veränderung push printtext zu push $printtext.
So wie es ist, laden Sie einen Wert von der Adresse printtext und das zu pushen, anstatt die Adresse zu pushen. Somit passierst du 'test' als 32-Bit-Zahl und nicht als Zeiger und printf versucht das als Adresse zu interpretieren und stürzt ab.
Eine der besten Möglichkeiten, mit Assemblersprachenfunktionen zu beginnen, besteht darin, eine ähnliche Funktion in C zu schreiben und sie dann mit dem Compilerschalter zu erstellen, der eine Assemblerliste generiert (-S auf gcc). Dann können Sie die Ausgabe des Compilers untersuchen und nach Bedarf ändern.
Dies ist besonders nützlich, wenn Sie Funktionen wie aufrufen printf die eine andere Aufrufkonvention verwenden (wegen der variablen Anzahl von Argumenten). Das Aufrufen dieser Funktionen kann sich stark vom Aufrufen von Nicht-Vargs-Funktionen unterscheiden.
Sehr lehrreich … aber normalerweise auch sehr irreführend. Das eigentliche Problem sind die ABI-spezifischen Details darüber, welche Register aufbewahrt werden müssen, was sie bedeuten und wie sie mit dem C ABI interagieren. Ich bin zunächst diesen Weg gegangen und habe dann festgestellt, dass meine Assembly nicht besser sein würde als das, was der Compiler generieren würde, was genau das Gegenteil von dem war, was ich erreichen wollte!
– bum
14. Januar 2011 um 4:52 Uhr
Das Problem war, dass ich verwendet habe
pushl printtext
lieber das
pushl $printtext
Vielen Dank an alle für Ihre Hilfe und entschuldigen Sie die Zeitverschwendung 😛
Du hast es bekommen, kurz bevor ich gepostet habe. Herzlichen Glückwunsch zur Lösung Ihres Problems. 🙂
– R.. GitHub HÖR AUF, EIS ZU HELFEN
13. Januar 2011 um 4:16 Uhr
asveikau
Danach:
push printtext
call printf
Sie wollen:
addl $4, %esp
Weitere Erklärung:
Da Sie x86-Linux verwenden, gehe ich davon aus, dass die Aufrufkonvention erfordert, dass der Angerufene die Parameter bereinigt. Weil Sie vor dem Anruf einen Zeiger gedrückt haben printfist Ihr Stack nach dieser Funktion um 4 weg ret Anweisung passiert.
Aktualisieren:
Ja, OK, ich war an die Intel-Syntax gewöhnt, also bekam ich die Reihenfolge der Argumente in meinem Kopf rückwärts. Eigentlich das Fehlen der addl zurück zu esp spielt keine Rolle, weil Sie wiederherstellen esp richtig in Ihrer Nähe ret. Meine nächste Vermutung ist, dass die Zeichenfolge, an die Sie übergeben werden printf fehlt ein Null-Terminator … Mal sehen, was gas tut…
Aktualisierung 2:
OK, gas null beendet Zeichenfolgen für Sie, also denke ich, dass meine zweite Vermutung falsch war. Es sieht so aus, als hätten Sie das Problem gefunden, also ist der Punkt strittig.
13569600cookie-checkAufruf von Assembly-Funktionen von cyes
“Irgendwelche Hinweise wären willkommen”: int *ptr;
– Saph
13. Januar 2011 um 3:55 Uhr
@Sapph +1 aber es hilft nicht :))
– Benutzer173973
13. Januar 2011 um 3:56 Uhr
@Sapph: Du meinst
void
*, Rechts?– Benutzer541686
13. Januar 2011 um 4:04 Uhr
@Lambert: Es ist im Nachhinein so schmerzlich offensichtlich! Ich schäme mich. +1 für Sie, mein Herr.
– Saph
13. Januar 2011 um 4:42 Uhr