2014-04-03 74 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