Wie kompiliere ich Montag Routinen für die Verwendung mit einem C-Programm (GNU Assembler)?

StackOverflow https://stackoverflow.com/questions/808948

Frage

Ich habe eine Reihe von Montagefunktion, die ich durch die Schaffung einer Header-Datei in C-Programme verwenden möchten. Zum Beispiel, wenn ich asm_functions.s haben, die definiert die eigentliche Montage Routinen und asm_functions.h die Prototypen für die Funktionen sowie einige Standard # hat definieren die ich brauchte. Mein Ziel ist es, ein C-Programm zu verwenden, sagen test_asm.c die Montage Funktionen aufzurufen.

asm__functions.h:


 #define ASM_CONST_1    0x80
 #define ASM_CONST_2    0xaf

uint8_t asm_foo( int, int, int );

asm__functions.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

test__asm.c:


 #include "asm_foo.h"

int main() { uint8_t res = asm_foo( 1, 2, 3); return 0; }

In einer Situation wie dieser, was der richtige Weg wäre, einen Link, um das Programm zu kompilieren? Ich war so etwas wie dies versuchen:


gas -o asm_foo.o asm_foo.s
gcc -o test_asm test_asm.c

Aber ich habe noch einen Linker-Fehler von GCC erhalten, dass meine Assembly-Routine nicht definiert ist. Ich hoffe, das erfundene Beispiel gut genug ist, um die Situation zu erklären.

Danke!

EDIT:

Hier ist ein Ausschnitt des Ausgangs, wenn ich mit einem einzigen Befehl kompilieren:


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 toPCI_FUNCTION_ID'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0xa): undefined reference toREAD_CONFIG_BYTE'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x18): undefined reference toPCI_BIOS_FUNCTION_INT'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x1b): undefined reference toBAD_REGISTER_NUMBER'
/tmp/ccY0SmMN.o: In function _pci_bios_read_word':
(.text+0x30): undefined reference toPCI_FUNCTION_ID'
...

Alle diese, wie PCI_FUNCTION_ID, sind in meiner Header-Datei definiert, die von dem C-Programm enthalten ist. Wenn ich den Assembler-Code von selbst kompilieren keine Fehler vorhanden sind.

War es hilfreich?

Lösung

Basierend auf den Dateien in Ihrer Frage, schaffte ich es zu kompilieren. Ich habe sowohl die Dateinamen und die Dateiinhalte verändert.

asm_const.h:

#define ASM_CONST_1    0x80
#define ASM_CONST_2    0xaf

asm_functions.h:

#include "asm_const.h"
unsigned char asm_foo( int, int, int );

asm_functions.S (die hintere S Kapital sein muss # include braucht es!):

#include "asm_const.h"
.section .text
.globl asm_foo
.type asm_foo, @function
asm_foo:
  mov $ASM_CONST_1, %eax
  /* asm code with proper stack manipulation for C calling conventions */
  ret

test_asm.c:

#include "asm_functions.h"
int main() {
  return asm_foo( 1, 2, 3);
}

Bitte beachten Sie, dass Sie benötigen, die die Montagedateierweiterung mit einem Kapital S. Mit .s .S würde die .s-Datei nicht durch den Präprozessor ausgeführt werden, so würde # include nicht funktioniert, und Sie würden nicht sein Lage ASM_CONST_1 in der .s-Datei zu verwenden.

Übersetzen mit einem einzigen Befehl:

gcc -o test_asm asm_functions.S test_asm.c

Oder als Alternative kompilieren mit mehreren Befehlen, die Schaffung .o Dateien:

gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o

Der Single-Befehl gcc nimmt die .S-Datei Kompilieren unter Verwendung von Gas, die C-Datei mit GCC C Compiler und der Verknüpfung des resultierenden temporären .o-Dateien zusammen ld verwenden. gcc läuft all diese Befehle mit dem entsprechenden Flags in der Standardeinstellung.

Auf manchen Systemen (aber nicht auf Linux mit der Standard-GCC-Installation) Sie haben einen Unterstrich auf die Namen der exportierten Funktionen in der .S-Datei vorangestellt wird (aber nicht in der .c oder .h-Dateien). So werden alle Instanzen von asm_foo würde _asm_foo nur in der .S-Datei.

Andere Tipps

Haben Sie darüber nachgedacht Inline-Assembler mit? Es wäre viel einfacher, als eine Assembler-Datei.

Edit: Auch der Grund, warum Sie Linker Fehler bekommen ist wahrscheinlich, weil die C-Compiler ein führende auf Identifikatoren für die tatsächlichen Symbole Strich ergänzt. Versuchen Sie, einen Unterstrich in der Baugruppendatei.

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