Pregunta

Tengo un conjunto de funciones de ensamblaje que quiero usar en programas en C creando un archivo de encabezado. Por ejemplo, si tengo asm_functions.s que define las rutinas de ensamblaje reales y asm_functions.h que tiene prototipos para las funciones, así como algunas # definiciones estándar que necesitaba. Mi objetivo es usar un programa en C, digamos test_asm.c para llamar a las funciones de ensamblaje.

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

En una situación como esta, ¿cuál sería la forma correcta de compilar un enlace del programa? Estaba intentando algo como esto:


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

Pero sigo recibiendo un error de enlace de GCC que dice que mi rutina de ensamblaje no está definida. Espero que este ejemplo artificial sea lo suficientemente bueno como para explicar la situación.

¡Gracias!

EDITAR:

Aquí hay un fragmento de salida cuando compilo con un solo comando:


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

Todos estos, como PCI_FUNCTION_ID, están definidos en mi archivo de encabezado, que está incluido en el programa C. Cuando compilo el código de ensamblaje solo, no hay errores.

¿Fue útil?

Solución

Basado en los archivos en su pregunta, logré compilarlo. He cambiado los nombres y el contenido del archivo.

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 (¡la S final debe ser mayúscula! #include lo necesita):

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

Tenga en cuenta que necesita la extensión del archivo de ensamblaje .S con mayúscula S. Con .s, el archivo .s no se ejecutará a través del preprocesador, por lo tanto, #include no funcionaría y usted no estaría capaz de usar ASM_CONST_1 en el archivo .s.

Compilar con un solo comando:

gcc -o test_asm asm_functions.S test_asm.c

O, como alternativa, compile con múltiples comandos, creando archivos .o:

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

El comando único gcc se encarga de compilar el archivo .S usando gas, el archivo .c con el compilador C de GCC y vincular los archivos temporales .o resultantes usando ld. gcc ejecuta todos esos comandos con las banderas apropiadas por defecto.

En algunos sistemas (pero no en Linux con la instalación predeterminada de GCC) debe anteponer un guión bajo a los nombres de las funciones exportadas en el archivo .S (pero no en los archivos .c o .h). Por lo tanto, todas las instancias de asm_foo se convertirían en _asm_foo solo en el archivo .S.

Otros consejos

¿Ha considerado usando el ensamblaje en línea ? Sería mucho más fácil que usar un archivo ensamblador.

Editar: Además, la razón por la que está obteniendo errores de enlazador probablemente se deba a que el compilador de C agrega un guión bajo en los identificadores para los símbolos reales. Intente agregar un guión bajo en su archivo de ensamblaje.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top