2011-04-10 16 views
2

我寫了一個簡單的彙編軟件(nasm)和一個簡單的C應用程序。我的C代碼從彙編代碼中調用了一個函數,但是我不知道如何編譯C代碼而沒有收到'未定義的參考'來自'extern int Sum()'的錯誤''線。如何鏈接ELF32程序集和C文件?

C代碼:

#include <stdio.h> 

extern int Sum(); 

main() 
{ 
    int a1, a2, x; 

    x = Sum(a1, a2); 
    printf("value of x is: %d\n", x); 
} 

彙編代碼:

global _Sum 

_Sum: 
    push ebp 
    mov ebp, esp 

    mov eax, [ebp+8] 
    mov ecx, [ebp+12] 
    add eax, ecx 
    pop ebp 
    ret 

我將如何分別編譯這兩個文件,之後將它們鏈接在一起成一個統一的文件?

+0

我知道這個問題是舊的:然而,人誰在這裏 - 鏈接的代碼,我已經在我的回答如下提供的參考書籍是巨大的資源來學習部件。希望你有機會檢查一下! – Arvind 2012-11-20 12:48:17

回答

0

最常用的方法是使用GCC工具鏈獲取C程序的彙編代碼,然後手動彙編兩個彙編文件並將它們鏈接起來。

+0

謝謝。但有沒有辦法將代碼鏈接在一起,而不使用GCC生成的程序集? – Benjamin 2011-04-10 14:52:35

+0

你在說什麼是編譯過程的兩個不同階段 - 組合和鏈接。要手動鏈接文件,您可以使用標準的'ld'工具。 – iehrlich 2011-04-10 15:01:25

+0

我知道,但問題在於,當我組裝.asm文件時。沒問題。我得到一個.o文件。當我用GCC編譯.c文件時,它給了我一個有關'Sub'的未定義引用的錯誤,但我無法鏈接這些文件,從而在編譯.c文件之前清除錯誤。這是我的困境。 – Benjamin 2011-04-10 15:04:06

2

您應該組裝.asm文件以獲取.o(對象)文件,就像您所說的那樣。然後,你應該編譯(但不鏈接).c文件得到另一個.o文件將,這樣的:

gcc -o whatever.o -c whatever.c 

,那麼你應該將它們關聯起來,就像這樣:

gcc whatever.o asm.o 

,則鏈接將與所有對象代碼一起運行,並且應該能夠解析它需要的引用。

+0

謝謝你的答案,但這只是給了我這個錯誤:main.o:在函數'main'中: main.c :(。文本+ 0x1f):未定義引用'總和' collect2:ld返回1退出狀態 – Benjamin 2011-04-10 15:46:43

+0

...當你運行第一個命令或第二個?你能粘貼你運行的所有命令直到第一次失敗嗎? – 2011-04-10 15:50:44

+0

另外,你可以使用objdump或類似的方式來轉儲你的彙編代碼對象文件的內容,所以我們可以看到它實際包含的符號嗎? – 2011-04-10 15:52:23

2

在與ELF一起使用的ABI中,C名不會與最初的_重疊。

+0

mangling是由編譯器決定的,而GCC使用下劃線 – 2011-07-20 17:59:12

+0

@Foo修改C函數名稱,GCC執行目標ABI所需的操作,並且我知道ELF沒有使用與初始'_'一起使用C名稱的ELF。如果需要,GCC將針對其他ABI進行調整。 – AProgrammer 2011-07-20 19:26:37

1

有兩種方法可以解決這個問題,編譯C源代碼爲C(C++),將其編譯爲C,你必須給它的擴展名.c

的第二種方式,在C++代碼(擴展名。 cpp)的名稱被破壞,當您編譯C++代碼時,使用十六進制編輯器查看目標文件並搜索Sum。在我的情況下,名字變成_Z3Sumii。如果您將彙編源代碼中的名稱更改爲此,則會發現它的工作原理。

而且改變在C++源extern語句以下,因爲它需要int類型的兩個參數,例如,extern int Sum(int, int);

global _Z3Sumii 
_Z3Sumii: 
    push ebp 
    mov ebp, esp 
    mov eax, [ebp+8] 
    mov ecx, [ebp+12] 
    add eax, ecx 
    mov esp, ebp 
    pop ebp 
    ret 

要編譯:

gcc -c file.cpp 
nasm -f elf32 sum.asm -o sum.o 
gcc file.o sum.o -o file 
0

在你的情況:

nasm -f elf -o sumasm.o sumasm.asm 
gcc -o sum sumasm.o sum.c 

你可能需要elf32

1

有人誰到這裏來尋找:檢查出在這裏http://www.drpaulcarter.com/pcasm/index.php代碼和書:在here Downloadthe Linux的例子:你想引用的文件是first.asm - (根據編譯架構:低於32位的例子)

nasm -f elf -d ELF_TYPE asm_io.asm 
nasm -f elf32 first.asm 
gcc -o first first.o driver.c asm_io.o