Jak skompilować procedury assemblera do użycia z programem C (GNU assembler)?

Mam zestaw funkcji assembly, które chcę wykorzystać w programach C, tworząc plik nagłówkowy. Na przykład, jeśli mam asm_functions.s, która definiuje rzeczywiste procedury asm_functions i asm_functions.h, który ma prototypy dla funkcji, jak również niektóre standardowe # define ' s i potrzebne. Moim celem jest użycie programu w języku C, powiedzmy test_asm.c do wywołania funkcji montażu.

ASM__funkcje.h:


 #define ASM_CONST_1    0x80
 #define ASM_CONST_2    0xaf

Uint8_t asm_foo( int, int, int );

ASM__funkcje.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; }

W sytuacji jaki byłby właściwy sposób kompilacji linku do programu? Próbowałem czegoś takiego:


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

Ale nadal dostaję błąd linkera z GCC mówiący, że moja procedura montażu jest niezdefiniowana. Mam nadzieję, że ten wymyślony przykład jest wystarczająco dobry, aby wyjaśnić sytuację.

Dzięki!

EDIT:

Oto fragment wyjścia podczas kompilacji za pomocą jednego polecenia:


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

Wszystkie z nich, takie jak PCI_FUNCTION_ID, są zdefiniowane w moim pliku nagłówkowym, który jest dołączony do programu C. Podczas kompilacji kodu asemblera nie ma żadnych błędów.

Author: Mr. Shickadance, 2009-05-01

2 answers

Bazując na plikach w twoim pytaniu, udało mi się je skompilować. Zmieniłem zarówno nazwy plików, jak i zawartość pliku.

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 (końcowe S musi być kapitalne! # include needs it):

#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);
}

Pamiętaj, że potrzebujesz rozszerzenia pliku assembly .S z kapitałem S. Z .s, the .plik s nie byłby uruchamiany przez preprocesor, więc #include nie działałby, a nie będzie można użyć ASM_CONST_1 w .plik S.

Skompiluj jednym poleceniem:

gcc -o test_asm asm_functions.S test_asm.c

Lub, jako alternatywę, kompilować z wieloma poleceniami, tworząc .o pliki:

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

Pojedyncze polecenie gcc zajmuje się kompilacją .S file using gas, the .plik c z kompilatorem C GCC i łączący wynikowy tymczasowy .o Pliki razem za pomocą ld. gcc domyślnie uruchamia wszystkie te polecenia z odpowiednimi flagami.

Na niektórych systemach (ale nie na Linuksie z domyślna instalacja GCC) musisz dodać podkreślenie do nazw wyeksportowanych funkcji w .Plik S (ale nie w .c lub .pliki h). Tak więc wszystkie instancje asm_foo staną się _asm_foo tylko wPlik S.

 14
Author: pts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-27 15:53:47

Czy rozważałeś Użycie inline assembly ? Byłoby to o wiele łatwiejsze niż użycie pliku asemblera.

Edit: również powodem, dla którego dostajesz błędy linkera, jest prawdopodobnie to, że kompilator C dodaje główny podkreślnik na identyfikatorach dla rzeczywistych symboli. Spróbuj dodać podkreślenie w pliku złożenia.

 0
Author: Zifre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 20:43:32