【发布时间】:2015-03-28 07:42:29
【问题描述】:
我在一个文件 (original_fun.c) 中定义了一个函数 original_fun,我需要在文件 use_alias.c 中将其称为 global_alias。我尝试了以下方法:
# set_alias.s
.globl global_alias
.set global_alias, original_fun
// original_fun.c
#include <stdio.h>
void original_fun(int x)
{
printf("original_fun(%d)\n", x);
}
// use_alias.c
extern void global_alias(int x);
int main()
{
global_alias(42);
return 0;
}
但是符号global_alias没有被导出:
$ as set_alias.s -o set_alias.o
$ clang original_fun.c -c -o original_fun.o
$ clang use_alias.c -c -o use_alias.o
$ clang set_alias.o original_fun.o use_alias.o -o result
use_alias.o: In function `main':
use_alias.c:(.text+0x1d): undefined reference to `global_alias'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
还有objdump 报告:
$ objdump -rt set_alias.o
set_alias.o: file format elf32-i386
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 *UND* 00000000 original_fun
(鼓舞人心的例子是original_fun 是一个错位的 C++ 名称,我想以更简洁的名称导出它,以便在汇编程序中轻松使用它。)
GAS 手册 (https://sourceware.org/binutils/docs/as/Set.html) 声明如下:
如果您 .set 一个全局符号,则存储在目标文件中的值是最后存储的值。
这可能与我的问题有关,但我不确定我是否理解正确。
【问题讨论】:
-
我的答案是使用
extern "C"或重新考虑您的设计。为什么需要从程序集中调用函数?不使用重载会解决问题吗?这是唯一被声明为extern "C"的重载吗?您可以使用声明为extern "C"的入口函数吗?如果该函数需要您使用汇编生成的数据,为什么这不在一个可以从original_fun调用的自包含汇编过程中,而不是像您尝试做的相反的方式? -
我需要从汇编中调用函数(并引用常量),因为汇编器是从编译器输出的,而 C++ 是运行时库的语言。即使没有重载,函数的名称也会被破坏,因为编译器永远无法确定以后或在另一个文件中不会有任何重载。
标签: c assembly gnu-assembler