我有这个简单的C源代码:
#include <stdio.h>
extern int Sum(int,int);
int main()
{
int a,b,s;
a=1 , b=2;
s = Sum(a,b);
return 0;
}
我有这个s.asm定义函数_Sum:
global _Sum
_Sum:
push ebp ; create stack frame
mov ebp, esp
mov eax, [ebp+8] ; grab the first argument
mov ecx, [ebp+12] ; grab the second argument
add eax, ecx ; sum the arguments
pop ebp ; restore the base pointer
ret
现在,我使用:
编译了.asmnasm s.asm -f elf -o s.o
使用以下方法编译和链接.c文件:
gcc s.o test.o -o testapp
这是结果:
/tmp/ccpwYHDQ.o: In function `main':
test.c:(.text+0x29): undefined reference to `Sum'
collect2: ld returned 1 exit status
那么问题是什么?
我正在使用Ubuntu-Linux
非常感谢任何帮助,谢谢
[求助]:我用nm检查了test.o文件,它预计会找到符号'Sum'而不是'_Sum',所以改变它就解决了这个问题。
答案 0 :(得分:7)
在典型的汇编程序中,标签默认为本地标签。要告诉汇编程序使它们对外部例程可见,您必须添加一个声明,例如:
.globl _Sum
此外,在C中正确声明例程。这不是导致链接错误的原因,但可能导致其他问题:
extern int Sum(int, int);
为了完整性,感谢评论者:不要覆盖您的目标文件。您可以汇编,编译和链接:
nasm s.asm -f elf -o s.o
gcc test.c s.o -o test
(这命名可执行文件“test”,您可能必须使用“./test”执行它以区分目录中的“test”和“test”命令。您可能更乐意选择其他名称。 )
出于教育目的:如果您的系统上有nm
工具,请执行命令nm s.o
。它可能会显示如下:
00000000 t _Sum
t
表示_Sum
是代码部分中的本地标签。 (代码部分也称为文本部分,因此也称为t。)添加.globl
声明并汇总新源后,nm s.o
应显示大写T
。大写表示标签在外部可见。
答案 1 :(得分:4)
据我所知,你可以用C程序覆盖来自汇编程序s.o
的目标文件。所以你不再拥有汇编程序了。
你应该写
生成s.o
目标文件
nasm s.asm -f elf -o s.o
生成test.o
(您的命令创建了另一个s.o)
gcc test.c -c
关联应用
gcc s.o test.o -o testapp
(我选择testapp作为输出二进制文件,因为test
通常是一个非常糟糕的程序名称,它与Unix命令test
碰撞
答案 2 :(得分:0)
最好在c文件中声明asm内联。以下是我自己的代码中的示例:
bool KxMutex::tryLock_i()
{
#ifdef KX_MUTEX_ASM
int oldLock;
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
asm volatile (
"movl $1,%%eax\n\t"
"xchg %%eax,%0\n\t"
"movl %%eax,%1\n\t"
: "=m" (mLock), "=m" (oldLock)
:
: "%eax", "memory"
);
#elif defined(__GNUC__) && (defined(__ppc__))
int newLock = 1;
asm volatile (
"\n1:\n\t"
"lwarx %0,0,%1\n\t"
"cmpwi 0,%0,0\n\t"
"bne- 2f\n\t"
"stwcx. %2,0,%1\n\t"
"bne- 1b\n\t"
"isync\n"
"2:\n\t"
: "=&r" (oldLock)
: "r" (&mLock), "r" (newLock)
: "cr0", "memory"
);
#endif
return ( oldLock == 0 );
#else // !KX_MUTEX_ASM
return ( pthread_mutex_trylock( (pthread_mutex_t*)this ) ? false : true );
#endif // !KX_MUTEX_ASM
}
有许多优点: