Aufruf von Assembly-Funktionen von c

Lesezeit: 3 Minuten

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

int do_shit_in_asm()

In der .asm-Datei habe ich

.extern printf
.section .data
         printtext:
              .ascii "test"
.section .text
.global do_shit_in_asm
.type do_shit_in_asm, @function

do_shit_in_asm:
    pushl %ebp
    movl %esp, %ebp
    push printtext
    call printf
    movl %ebp, %esp
    pop %ebp
ret

Irgendein Zeiger Kommentare wären willkommen.

as func.asm -o func.o

gcc prog.c func.o -o prog

  • “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

Benutzer-Avatar
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.

1356960cookie-checkAufruf von Assembly-Funktionen von c

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy