Frage

Ich versuche, in der Montage eine Funktion zu verwenden, aufgerufen von einem C-Projekt. Diese Funktion soll eine libc-Funktion lassen Sie uns sagen printf() nennen, aber ich erhalte einen Segmentation Fault zu bekommen.

In der C-Datei Ich habe die Erklärung der Mitsprache Funktion dient

int do_shit_in_asm()

In der .asm Datei Ich habe

.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

Jeder Zeiger Kommentare geschätzt würde.

as func.asm -o func.o

gcc prog.c func.o -o prog
War es hilfreich?

Lösung

Ändern push printtext zu push $printtext.

Wie es ist, werden Sie einen Wert aus der Adresse printtext Laden und schieben, anstatt die Adresse drücken. So sind Sie 'test' als 32-Bit-Zahl, anstatt ein Zeiger vorbei, und printf versuchen, dass als eine Adresse zu interpretieren und abstürzt.

Andere Tipps

Eine der besten Möglichkeiten, um mit Assembler-Sprache-Funktionen, um loszulegen ist eine ähnliche Funktion in C, zu schreiben und bauen es dann mit dem Compiler-Schalter, der eine Montag Listing (-S auf gcc) erzeugt. Dann können Sie die Ausgabe von studieren, was der Compiler getan hat, und bei Bedarf ändern.

Dies ist besonders nützlich, wenn Sie Funktionen wie printf sind aufrufen, die eine andere Aufrufkonvention verwenden (wegen der variablen Anzahl von Argumenten). diese Funktionen aufrufen können ganz unterschiedlich sein Aufruf nicht-varargs Funktionen.

das Problem war, dass ich mit

pushl printtext

vielmehr, dass

pushl $printtext

Vielen Dank allen für Ihre Hilfe und sorry für Ihre Zeit verschwenden: P

Danach:

push printtext
call printf

Sie möchten:

addl $4, %esp

Eine weitere Erläuterung:

Weil Sie mit x86 Linux ich die Aufrufkonvention übernehmen muss der Angerufene zur Reinigung der Parameter. Weil Sie einen Zeiger vor dem Aufruf printf geschoben, Ihre Stapel von 4, nachdem diese Funktion der ret Anweisung off passiert ist.

Update:

Ja, OK, ich war auf Intel-Syntax verwendet, so dass ich die Reihenfolge der Argumente nach hinten in meinem Kopf zu bekommen. Eigentlich tut das Fehlen der addl zurück zu esp keine Rolle, da Sie esp richtig in der Nähe Ihrer ret sind wiederherzustellen. Meine nächste Vermutung ist, dass der Zeichenfolge Sie vorbei an printf ist eine Null-Terminator fehlen ... Lassen Sie mich sehen, was gas tut ...

Update 2:

OK, gas null beendet Strings für Sie, so dass ich meine zweite Vermutung erraten war falsch. Es sieht aus wie Sie das Problem gefunden, so der Punkt strittig ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top