Aufruf Montagefunktionen von c
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
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.