Aufrufen von C-Funktionen, die von x86 assembly language
Ist es möglich, zum generieren von Assembler-Funktionen von C-Funktionen mit GCC, so dass Sie aufgerufen werden, aus der eine assembly-Sprache-Programm? Ich weiß, dass gcc kompiliert die C-zu-Maschine-code (die leicht zerlegt werden, in Assembler), und ich weiß schon, dass es möglich ist,inline-Assembler-Funktionen in C, aber ich habe noch nicht einen Weg gefunden, zum aufrufen von C-Funktionen aus dem Assembler-Programme, die im Grunde ist die Antwort.
Hier bin ich versucht, inline-einer C-Funktion in ein x86-Assembler-Programm. Wenn inlining nicht möglich ist, dann gibt es eine andere Möglichkeit zum aufrufen einer C-Funktion aus Assembler-Programm?
.686p
.model flat,stdcall
.stack 2048
.data
.code
start:
invoke ExitProcess, 0
printSomething PROC ;now I'm attempting to inline a C function here
void printSomething(thingToPrint){
printf("This is a C function that I want to invoke from an assembly language program.");
printf("There must be some way to do this - is it possible somehow?");
}
printSomething ENDP
end start
- Ich erinnere mich nicht alle details, aber Sie brauchen nur zu kompilieren, um Objekt-Dateien und verlinken Sie Sie. Sie müssen nur wissen, was Aufrufkonventionen verwendet werden, dass beim Aufruf der Funktion.
- Man könnte hinzufügen, der Assembler-code, der zeigt, was Sie versucht haben, und sagen, wie es nicht kompiliert werden kann oder wie sich es verhält sich falsch. Es wäre viel einfacher, für eine Antwort darauf hinweisen, was das problem mit ihm.
- Sie können lernen, wie Sie dies tun, indem er eine C-Funktion, die ruft die Funktion, die Sie anrufen möchten, kompilieren Sie es, um Assembler (
-S
), und Untersuchung der Ergebnisse. Ich würde auch den Punkt, den Sie bei der "psABI", aber ich kann nicht finden, eine Kopie mehr. - Natürlich können Sie dies tun. Befolgen Sie einfach die Regeln Ihres Compilers ' s ABI.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werde ich aus dem Gedächtnis hier, so dass ich können Sie leicht über ein detail oder zwei. Es sollte jedoch hoffe ich, dass genug, um Sie in die richtige Richtung gehen.
Sind Sie gehen zu müssen, zu sagen, die GCC-assembler, die eine routine printSomething() ist nicht definiert in der assembly-Datei. In 'C' wäre die extern Schlüsselwort. Für die Montage benötigen Sie .globl.
Wenn Sie mit einem anderen assembler als GCC, der keyword unterschiedlich sein können.
Die nächste große Frage ist: "wie gebe ich die Argumente'? Diese sehr viel hängt von Ihrem Prozessor UND OS. Da der Titel deiner Frage zeigt x86, werde ich davon ausgehen, dass Sie entweder 16-bit oder 32-bit-Modi und die standard-x86-ABI (im Gegensatz zu x86-64, die auch unterscheidet sich zwischen Windows und Linux). Der C-Parameter werden an die aufgerufene routine schob Sie in den Stapel. Sie sind auf dem Stapel von rechts nach Links.
So,
übersetzt ...
Fragen Sie sich vielleicht, was ist das
? Wir übergeben (aka geschoben) vier 32-bit-Argumente zu der routine (auf dem Stapel). Obwohl die routine weiß, zu erwarten, dass diese Argumente, es ist NICHT verantwortlich für die Grashüpfer aus dem Stapel. Der Aufrufer ist dafür verantwortlich, dass. So, nachdem wir wieder aus der routine, passen wir den stack-pointer zu verwerfen, die vier 32-bit-Argumente, die wir zuvor auf dem Stapel abgelegt.
Im obigen Beispiel gehe ich davon aus, dass wir den Betrieb im 32-bit-Modus. Wenn es 16-bit-Modus, es wäre ...
Merke ich, dass in deinem Beispiel printSomething() dauert nur ein (1) argument und in meinem Beispiel habe ich vier (4). So passen Sie meinem Beispiel, wie benötigt wird.
Für die letzten Schritte müssen Sie kompilieren Sie Ihre C-und assembly-Dateien in Objekt-Dateien, link-Objekt-Dateien und führen Sie anschließend.
Ich hoffe, das hilft.
leave
oder gleichwertige Anweisungen, bevor es zurück zum Aufrufer. Ich denke, dieaddl $0x10, %esp
in deinem Beispiel überflüssig.C
kompilieren extern Methoden vorangestellt_
? Also der Aufruf solltecall _printSomething
... ???Für x86_64, beachten Sie, dass Sie müssen vorsichtig sein, mit einigen zusätzlichen Dingen:
muss der Stapel 16-bit-ausgerichtet vor C Aufrufe.
Wenn Sie definieren Ihre Funktion in der Montage, die Funktion, die aufgerufen, Ihre Funktion, den Rückgabewert auf den stack, misaligning es, und so haben Sie, subtrahieren Sie 8 weitere byte irgendwie, in der Regel
push %rbp
.Dieser hat mich hier zum Beispiel: Warum funktioniert das aufrufen der C abort () - Funktion ein x86_64-assembly-Funktion führen zu segmentation fault (SIGSEGV) statt einem Abbruch-signal?
wenn du eine
call
von der Montage aus irgendeinem Grund (TODO-warum würdest du das tun wollen?) Sie haben Grund zur Sorge:Hier ist ein Beispiel: Aufruf von printf in der erweiterten inline-ASM