Comment compiler des routines d'assemblage à utiliser avec un programme C (assembleur GNU)?

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

Question

J'ai un ensemble de fonctions d'assemblage que je souhaite utiliser dans les programmes C en créant un fichier d'en-tête. Par exemple, si j’ai asm_functions.s qui définit les routines d’assemblage réelles et asm_functions.h qui comporte des prototypes pour les fonctions, ainsi que des définitions standard que j’avais besoin. Mon objectif est d’utiliser un programme C, par exemple test_asm.c, pour appeler les fonctions d’assemblage.

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

Dans une situation comme celle-ci, quelle serait la bonne façon de compiler un lien vers le programme? J'essayais quelque chose comme ça:


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

Mais GCC a quand même une erreur dans l’éditeur de liens, disant que ma routine d’assemblage n’était pas définie. J'espère que cet exemple artificiel est suffisant pour expliquer la situation.

Merci!

EDIT:

Voici un extrait de sortie lorsque je compile avec une seule commande:


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

Tous ceux-ci, tels que PCI_FUNCTION_ID, sont définis dans le fichier d’en-tête, inclus dans le programme C. Lorsque je compile le code de l'assembly par lui-même, il n'y a pas d'erreur.

Était-ce utile?

La solution

Sur la base des fichiers de votre question, j'ai réussi à le compiler. J'ai changé le nom et le contenu du fichier.

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 (le S final doit être majuscule! #include en a besoin):

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

Veuillez noter que vous avez besoin de l’extension de fichier d’assemblage .S avec majuscule S. Avec .s, le fichier .s ne serait pas exécuté par le préprocesseur, ainsi #include ne fonctionnerait pas et vous ne le seriez pas. capable d'utiliser ASM_CONST_1 dans le fichier .s.

Compiler avec une seule commande:

gcc -o test_asm asm_functions.S test_asm.c

Vous pouvez également compiler plusieurs commandes en créant des fichiers .o:

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

La commande unique gcc prend en charge la compilation du fichier .S en utilisant gas, le fichier .c avec le compilateur C de GCC, et la liaison des fichiers .o temporaires résultants à l'aide de ld. gcc exécute toutes ces commandes avec les drapeaux appropriés par défaut.

Sur certains systèmes (mais pas sous Linux avec l'installation par défaut de GCC), vous devez ajouter un trait de soulignement aux noms des fonctions exportées dans le fichier .S (mais pas dans les fichiers .c ou .h). Ainsi, toutes les instances de asm_foo deviendront _asm_foo uniquement dans le fichier .S.

Autres conseils

Avez-vous envisagé de utiliser l'assemblage en ligne ? Ce serait beaucoup plus facile que d’utiliser un fichier assembleur.

Éditer: la raison pour laquelle vous obtenez des erreurs d’éditeur de liens est probablement due au fait que le compilateur C ajoute un trait de soulignement sur les identificateurs des symboles eux-mêmes. Essayez d’ajouter un trait de soulignement dans votre fichier d’assemblage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top