Wie kann ich kompilieren von assembly-Routinen für die Verwendung mit einem C-Programm (GNU-assembler)?
Habe ich eine Reihe von Montage-Funktion, die ich nutzen möchte in C-Programmen durch die Erstellung einer header-Datei. Zum Beispiel, wenn ich asm_functions.s definiert die aktuelle assembly-Routinen und asm_functions.h die Prototypen für die Funktionen sowie einige standard #define ' s, die ich brauchte. Mein Ziel ist es, ein C-Programm, sagen test_asm.c zum aufrufen der assembly-Funktionen.
asm__ - Funktionen.h:
#define ASM_CONST_1 0x80
#define ASM_CONST_2 0xaf
uint8_t asm_foo( int, int, int );
asm__ - Funktionen.s:
/* dont need this: #include "asm_functions.h" */
.section .text
.type asm_foo, @function
asm__foo:
/* asm code with proper stack manipulation for C calling conventions */
ret
testen Sie__asm.c:
#include "asm_foo.h"
int main() {
uint8_t res = asm_foo( 1, 2, 3);
return 0;
}
In einer situation wie dieser, was wäre die richtige Art und Weise zu kompilieren einen link auf dem Programm? Ich war versucht, so etwas wie dieses:
gas -o asm_foo.o asm_foo.s
gcc -o test_asm test_asm.c
Aber ich bekomme immer noch ein linker-Fehler von GCC sagen, dass meine assembly-routine ist nicht definiert. Ich hoffe, dass dieses erfundene Beispiel ist gut genug, um die situation zu erklären.
Dank!
EDIT:
Hier ist ein Ausschnitt der Ausgabe, wenn ich das kompilieren mit einem einzigen Befehl:
tja@tja-desktop:~/RIT/SP2/latest$ gcc -o test_pci pci_config.s test_pci.c
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x8): undefined reference to
PCI_FUNCTION_ID'
/tmp/ccY0SmMN.o: In Funktion _pci_bios_read_byte':
(.text+0xa): undefined reference to
READ_CONFIG_BYTE'
/tmp/ccY0SmMN.o: In Funktion _pci_bios_read_byte':
(.text+0x18): undefined reference to
PCI_BIOS_FUNCTION_INT'
/tmp/ccY0SmMN.o: In Funktion _pci_bios_read_byte':
(.text+0x1b): undefined reference to
BAD_REGISTER_NUMBER'
/tmp/ccY0SmMN.o: In Funktion _pci_bios_read_word':
(.text+0x30): undefined reference to
PCI_FUNCTION_ID'
...
Alle diejenigen, die wie PCI_FUNCTION_ID, sind definiert in meine header-Datei, die enthalten ist, indem Sie das C-Programm. Wenn ich kompilieren der Assembler-code durch selbst gibt es keine Fehler.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Basierend auf den Dateien, die in Ihrer Frage, habe ich es geschafft, um es zu kompilieren. Ich habe mich verändert, die Datei-Namen und den Inhalt der Datei.
asm_const.h :
asm_functions.h :
asm_functions.S (das nachgestellte S sein muss Kapital! #include braucht es) :
test_asm.c :
Bitte beachten Sie, dass benötigen Sie die assembly-Datei-Erweiterung .S mit einem Kapital S. Mit .s, die .s Datei würde nicht ausgeführt werden durch den Präprozessor, also #include nicht funktionieren würde, und Sie wäre nicht in der Lage zu verwenden ASM_CONST_1 in der .s Datei.
Kompilieren mit einem einzigen Befehl:
Oder, als alternative, die Kompilierung mit mehreren Befehlen erstellen .o Dateien:
Single-Befehl gcc kümmert sich um die Kompilierung der .S Datei-mit-gas .c Datei mit GCC C-compiler, und die Verknüpfung der daraus resultierenden temporären .o-Dateien zusammen mit ld. gcc führt alle diese Befehle mit den entsprechenden flags standardmäßig aktiviert.
Auf manchen Systemen (nicht aber unter Linux mit den Standard-GCC-installation) Sie haben voranstellen eines Unterstrichs, um die Namen der exportierten Funktionen in der .S Datei (aber nicht in der .c oder .h-Dateien). Also alle Instanzen von
asm_foo
werden würde_asm_foo
nur in der .S Datei..note.GNU-stack
Abschnitt, um die assembly-routine zu unterdrücken, dass die ausführbare stack-flag auf Linux. Lesen Sie dieser für weitere Informationen.Haben Sie als die Verwendung von inline-assembly? Es wäre viel einfacher, als die Benutzung einer assembler-Datei.
Edit: also, der Grund, Sie werden immer linker-Fehler ist wahrscheinlich, weil der C-compiler fügt einem führenden Unterstrich auf der IDS für die eigentlichen Symbole. Versuchen Sie, ein Unterstrich in der assembly-Datei.