Как мне скомпилировать процедуры сборки для использования с программой на C (ассемблер GNU)? - PullRequest
9 голосов
/ 01 мая 2009

У меня есть набор функций сборки, которые я хочу использовать в программах на Си, создав файл заголовка. Например, если у меня есть asm_functions.s, который определяет фактические процедуры сборки, и asm_functions.h, в котором есть прототипы для функций, а также некоторые стандартные # define, которые мне нужны Моя цель - использовать программу на C, скажем test_asm.c, для вызова функций сборки.

asm__functions.h:

<code>
 #define ASM_CONST_1    0x80
 #define ASM_CONST_2    0xaf</p>

<p>uint8_t asm_foo( int, int, int );

asm__functions.s:

<code>
 /* dont need this: #include "asm_functions.h" */</p>

<p>.section .text
 .type asm_foo, @function
 asm__foo:
   /* asm code with proper stack manipulation for C calling conventions */
   ret

test__asm.c:

<code>
 #include "asm_foo.h"</p>

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

В такой ситуации, каков будет правильный способ составить ссылку на программу? Я пытался что-то вроде этого:

<code>
gas -o asm_foo.o asm_foo.s
gcc -o test_asm test_asm.c

Но я все еще получаю ошибку компоновщика от GCC, говорящую, что моя процедура сборки не определена. Я надеюсь, что этот надуманный пример достаточно хорош, чтобы объяснить ситуацию.

Спасибо!

EDIT:

Вот фрагмент вывода при компиляции с помощью одной команды:

<code>
tja@tja-desktop:~/RIT/SP2/latest$ gcc -o test_pci pci_config.s test_pci.c
/tmp/ccY0SmMN.o: In function <code>_pci_bios_read_byte':
(.text+0x8): undefined reference to</code>PCI_FUNCTION_ID'
/tmp/ccY0SmMN.o: In function <code>_pci_bios_read_byte':
(.text+0xa): undefined reference to</code>READ_CONFIG_BYTE'
/tmp/ccY0SmMN.o: In function <code>_pci_bios_read_byte':
(.text+0x18): undefined reference to</code>PCI_BIOS_FUNCTION_INT'
/tmp/ccY0SmMN.o: In function <code>_pci_bios_read_byte':
(.text+0x1b): undefined reference to</code>BAD_REGISTER_NUMBER'
/tmp/ccY0SmMN.o: In function <code>_pci_bios_read_word':
(.text+0x30): undefined reference to</code>PCI_FUNCTION_ID'
...

Все они, такие как PCI_FUNCTION_ID, определены в моем заголовочном файле, который включен в C-программу. Когда я сам компилирую ассемблерный код, ошибок нет.

Ответы [ 2 ]

15 голосов
/ 01 мая 2009

На основании файлов в вашем вопросе мне удалось его скомпилировать. Я изменил как имена файлов, так и их содержимое.

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):

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

Обратите внимание, что вам нужно расширение файла сборки .S с заглавной буквы S. С .s файл .s не будет проходить через препроцессор, поэтому #include не будет работать, и вы не будете возможность использовать ASM_CONST_1 в файле .s.

Компилировать с помощью одной команды:

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 заботится о компиляции файла .S с помощью gas, файла .c с компилятором GCC C и связывании полученных временных файлов .o с помощью ld. По умолчанию gcc запускает все эти команды с соответствующими флагами.

В некоторых системах (но не в Linux с установкой GCC по умолчанию) вам необходимо добавить подчеркивание к именам экспортируемых функций в файле .S (но не в файлах .c или .h). Таким образом, все экземпляры asm_foo станут _asm_foo только в файле .S.

0 голосов
/ 01 мая 2009

Рассматривали ли вы , используя встроенную сборку ? Это было бы намного проще, чем использовать файл на ассемблере.

Редактировать: Кроме того, причина, по которой вы получаете ошибки компоновщика, возможно, в том, что компилятор C добавляет начальное подчеркивание в идентификаторах для фактических символов. Попробуйте добавить подчеркивание в сборочный файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...