Как скомпилировать процедуры сборки для использования с программой C (GNU assembler)?
у меня есть набор функций сборки, которые я хочу использовать в программах C, создавая файл заголовка. Например, если у меня есть asm_functions.s, который определяет фактические процедуры сборки и asm_functions.h, который имеет прототипы для функций, а также некоторые стандартные #define, которые мне нужны. Моя цель-использовать программу на C, скажем test_asm.c созыв ассамблеи функции.
АСМ__функции.ч:
#define ASM_CONST_1 0x80
#define ASM_CONST_2 0xaf
uint8_t asm_foo( int, int, int );
АСМ__функции.с:
/* 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
проверить слово__ASM.с:
#include "asm_foo.h"
int main() {
uint8_t res = asm_foo( 1, 2, 3);
return 0;
}
в такой ситуации, что бы правильно составить ссылку на программу? Я пробовал что-то вроде этого:
gas -o asm_foo.o asm_foo.s
gcc -o test_asm test_asm.c
но я все еще получаю ошибку компоновщика от GCC, говоря, что моя процедура сборки не определена. Я надеюсь, что этот пример достаточно хорош, чтобы объяснить ситуация.
спасибо!
EDIT:
вот фрагмент вывода, когда я компиляции с помощью одной команды:
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 function _pci_bios_read_byte':
(.text+0xa): undefined reference to
READ_CONFIG_BYTE'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x18): undefined reference to
PCI_BIOS_FUNCTION_INT'
/tmp/ccY0SmMN.o: In function _pci_bios_read_byte':
(.text+0x1b): undefined reference to
BAD_REGISTER_NUMBER'
/tmp/ccY0SmMN.o: In function _pci_bios_read_word':
(.text+0x30): undefined reference to
PCI_FUNCTION_ID'
...
все они, такие как PCI_FUNCTION_ID, определены в моем файле заголовка, который включен программой C. Когда я компилирую код сборки сам по себе, ошибок нет.
2 ответов
основываясь на файлах в вашем вопросе, мне удалось его скомпилировать. Я изменил имена файлов и их содержимое.
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 (трейлинг S должен быть капитальным! #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);
}
обратите внимание ,что вам нужно расширение файла сборки.С капитала С. С .с,.файл не будет работать через препроцессор, таким образом, #include не будет работать, и вы не сможете использовать ASM_CONST_1 в .файл s.
Compile с помощью одной команды:
gcc -o test_asm asm_functions.S test_asm.c
или, в качестве альтернативы, компилировать с несколькими командами, создавая .o файлы:
gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o
одна команда gcc заботится о компиляции .Файл с помощью газа .C-файл с компилятором GCC C и связывание полученного временного .o файлы вместе с помощью ld. ССЗ выполняет все эти команды с соответствующим флаги по умолчанию.
в некоторых системах (но не в Linux с установкой GCC по умолчанию) вы должны добавить подчеркивание к именам экспортируемых функций в .S файл (но не в том .C или .H-файлы). Итак, все экземпляры asm_foo
станет _asm_foo
только в этом .S файл.
вы рассматривали использование встроенной сборки? Это было бы намного проще, чем использовать файл ассемблера.
Edit: кроме того, причина, по которой вы получаете ошибки компоновщика, вероятно, заключается в том, что компилятор C добавляет ведущее подчеркивание идентификаторов для фактических символов. Попробуйте добавить подчеркивание в файл сборки.