我的程序有问题。当我试图用汇编函数编译我的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.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

assembly对象的nm输出中有一些有趣的东西。首先,U _main告诉我们main()在那个对象中是未定义的,这意味着当我们链接程序时应该会找到它。这个文件不调用main(),所以我们真的不应该关心它。这是由可以安全移除的.global _main引起的。
接下来,factarial_asm的符号是小写的,而不是来自主c源的t中的T。显示为main()意味着符号只是源文件的本地符号,不会导出到其他文件。(在c中,这是tvoid function() {}之间的区别)。我们需要通过添加适当的static void function() {}指令来解决这个问题。
摘要:在程序集中,将.global更改为.global _main

关于c - 用汇编功能编译C程序,反之亦然,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22848690/

10-11 23:17
查看更多