我的程序有问题。当我试图用汇编函数编译我的C程序时,请使用以下代码行:
gcc -o program factarial.c
我明白了,我不知道为什么:
/tmp/ccFKqbDP.o: In function `main':
factarial.c:(.text+0x11): undefined reference to `factarial_asm'
collect2: ld returned 1 exit status
这是我的C代码:
#include <stdio.h>
extern void factarial_asm();
int main ()
{
factarial_asm (5);
return 0;
}
这是汇编代码:
.data
.text
.global _main
.type factarial_asm, @function
factarial_asm:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cmpl $1, %eax
je koniec
decl %eax
pushl %eax
call factarial_asm
movl 8(%ebp), %ebx
mull %ebx
koniec:
leave
ret
另外,当我试图使用这一行用c函数编译asm代码时:
gcc -o program factarial.s
我有个问题:
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
/tmp/ccWCmTBe.o: In function `main':
(.text+0x3): undefined reference to `factarial'
collect2: ld returned 1 exit status
这是我的asm代码:
SYSEXIT = 1
EXIT_SUCC = 0
SYSWRITE = 4
SYSCALL = 0x80
SYSREAD = 3
.align 32
.text
.global _main
main:
pushl $5
call factarial
movl $SYSEXIT, %eax
movl $EXIT_SUCC, %ebx
int $SYSCALL
我的C码是:
#include <stdio.h>
int factarial(int n)
{
if(n == 0) return 1;
else return n * factarial(n - 1);
}
我知道这有很多问题,但到目前为止,我正准备作为编译器和ld链接器,所以我不完全知道如何使用gcc。
另外,有谁能帮我准备makefile文件吗?
最佳答案
问题是每个编译行都试图在没有完整程序的情况下创建可执行文件。如果源文件的名称相同,扩展名不同,则会使事情变得有些复杂。
一个简单的选项是,这个命令:gcc -o program factarial.c factarial.s
。
或者,可以考虑编译但不链接单个源文件,然后将它们的对象链接在一起以构建可执行文件。假设您的源文件名为a.c
和b.s
,您将:
gcc -c a.c
gcc -c b.s
gcc -o program a.o b.o
最后(当然与你的问题无关),我相信你要找的词是
factorial
:)在程序集中仍然存在问题。首先,我重新创建了您的结果,如下所示:
$ gcc -c factarial.c
$ gcc -c factarial_asm.s
$ gcc -o program factarial.o factarial_asm.o
factarial.o: In function `main':
factarial.c:(.text+0xf): undefined reference to `factarial_asm'
collect2: error: ld returned 1 exit status
接下来,我使用
nm
命令检查对象文件:$ nm factarial.o
U factarial_asm
0000000000000000 T main
$ nm factarial_asm.o
U _main
0000000000000000 t factarial_asm
000000000000001a t koniec
assembly对象的
nm
输出中有一些有趣的东西。首先,U _main
告诉我们main()
在那个对象中是未定义的,这意味着当我们链接程序时应该会找到它。这个文件不调用main()
,所以我们真的不应该关心它。这是由可以安全移除的.global _main
引起的。接下来,
factarial_asm
的符号是小写的,而不是来自主c源的t
中的T
。显示为main()
意味着符号只是源文件的本地符号,不会导出到其他文件。(在c中,这是t
和void function() {}
之间的区别)。我们需要通过添加适当的static void function() {}
指令来解决这个问题。摘要:在程序集中,将
.global
更改为.global _main
。关于c - 用汇编功能编译C程序,反之亦然,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22848690/