2014-04-03 27 views
1

我的程序出了问题。当我尝试使用此行来编译我的C程序与assebly功能:用安装函数编译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; 
} 

这是assebly代码:

.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函数:

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 

这是我的汇编代码:

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文件?

谢谢你的所有建议。

回答

4

问题是您的每个编译行都尝试在没有完整程序的情况下创建您的可执行文件。如果源文件具有不同扩展名的同名文件,则会使事情变得复杂一些。

一个简单的选择是,此命令:gcc -o program factarial.c factarial.s

或者,您可能会考虑编译但不链接您的各个源文件,然后将它们的对象链接在一起以构建您的可执行文件。假设你的源文件被命名为a.cb.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 

里有nm输出一些有趣的事情装配对象。首先,U _main告诉我们,main()在该对象中是未定义的,这意味着当我们链接程序时应该找到它。这个文件不叫main(),所以我们真的不应该关心这个。这是由.global _main引起的,可以安全地将其删除。

接着,对factarial_asm符号是下壳体t,不从主C源在main()发现...被示出为tT意味着符号是本地的该源文件只,它不输出到其它。 (在C中,这是void function() {}static void function() {}之间的差值)。我们需要通过添加正确的.global指令来解决这个问题。

总结:在您的程序集中,将.global _main更改为.global factarial_asm

+0

好的,谢谢你的回答。我会试试:) – user3448282

+0

不幸的是,问题保持不变: [对不起,对于外部链接,但我希望它更清晰。](http://pastebin.com/ddgrvw2V) – user3448282

+1

我只注意到你的主要)是一个汇编函数。尝试将其从'main:'重命名为'_main:'。您可能还需要将'call factarial'改为'call _factarial'。 – mah