Mr.*_*nce 9 x86 assembly linker compilation
我有一组汇编函数,我希望通过创建头文件在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程序中.当我自己编译汇编代码时,没有错误.
pts*_*pts 15
根据你问题中的文件,我设法编译它.我已经更改了文件名和文件内容.
asm_const.h:
#define ASM_CONST_1 0x80
#define ASM_CONST_2 0xaf
Run Code Online (Sandbox Code Playgroud)
asm_functions.h:
#include "asm_const.h"
unsigned char asm_foo( int, int, int );
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
test_asm.c:
#include "asm_functions.h"
int main() {
return asm_foo( 1, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要使用大写字母S的汇编文件扩展名.S..s,.s文件不会通过预处理器运行,因此#include不起作用,您将无法使用.s文件中的ASM_CONST_1.
使用单个命令编译:
gcc -o test_asm asm_functions.S test_asm.c
Run Code Online (Sandbox Code Playgroud)
或者,作为替代方案,使用多个命令进行编译,创建.o文件:
gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o
Run Code Online (Sandbox Code Playgroud)
单命令gcc负责使用gas编译.S文件,使用GCC的C编译器编译.c文件,并使用ld将生成的临时.o文件链接在一起.默认情况下,gcc使用适当的标志运行所有这些命令.
在某些系统上(但不是在安装了默认GCC的Linux上),您必须在.S文件中的导出函数名称前加下划线(但不包括.c或.h文件中).所以所有实例asm_foo都_asm_foo只会出现在.S文件中.