我有一组汇编函数,我希望通过创建头文件在C程序中使用它。例如,如果我有定义实际汇编例程的asm_functions.s和asm_functions.h,它们具有函数原型以及我需要的一些标准#define。我的目标是使用C程序,比如test_asm.c来调用汇编函数。

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

在这样的情况下,编译链接程序的正确方法是什么?我正在尝试这样的事情:


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

但我仍然从GCC得到一个链接器错误,说我的程序集例程未定义。我希望这个人为的例子足以解释这种情况。

谢谢!

编辑:

使用单个命令编译时,这是一个输出片段:


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

所有这些,例如PCI_FUNCTION_ID,都在我的头文件中定义,该文件包含在C程序中。当我自己编译汇编代码时,没有错误。

有帮助吗?

解决方案

根据你问题中的文件,我设法编译它。我已经更改了文件名和文件内容。

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不起作用,并且您不会能够在.s文件中使用ASM_CONST_1。

使用单个命令进行编译:

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负责使用gas编译.S文件,使用GCC的C编译器编译.c文件,并使用ld将生成的临时.o文件链接在一起。 gcc默认使用适当的标志运行所有这些命令。

在某些系统上(但在具有默认GCC安装的Linux上),您必须在.S文件中的导出函数名称前加下划线(但不包括.c或.h文件中)。因此 asm_foo 的所有实例只会在.S文件中变为 _asm_foo

其他提示

您是否考虑过使用内联汇编?它比使用汇编程序文件容易得多。

编辑:此外,您获得链接器错误的原因可能是因为C编译器在实际符号的标识符上添加了前导下划线。尝试在程序集文件中添加下划线。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top