2013-02-23 101 views
4

我回來了C/C++和ASM,我想玩一點點火。我發現,當您編譯代碼並將其鏈接到Windows的可執行文件時,它會動態鏈接到某些需要運行該應用程序的計算機上必須存在的庫。您可以指定編譯器不與它們鏈接,併爲此創建自己的庫。在C或程序集中製作一個簡單的CRT0

除此之外(如果我在這裏所說的一切都錯了,請糾正我),這裏有一個目標文件,它總是遵從我們應用程序的主代碼並與其鏈接。它是crt0.o(C運行時)文件,據我所知,它準備堆棧,獲取argc和argv並調用主函數(也可能是其他的東西)。我也相信這是系統在執行應用程序時調用的第一段代碼。

所以,我想創建一個簡單的crt0.obj並將其鏈接對一個簡單的C++對象文件

int main(int argc, char** argv) { 
    return 0; 
} 

我用GCC,我想利用沒有標準庫,所以我的命令看起來像:

g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe crt0.o 

我假設-nostartfiles指令是什麼告知鏈接無法嵌入默認的crt0.o,所以希望我給每個定義的任何功能和處理的啓動應用程序。我在這裏有點困惑。

無論如何,我想創建一個非常基本的crt0目標文件,這足以讓GCC創建我的可執行文件,並讓系統啓動它。我知道互聯網上有很多代碼文件(C和ASM),但我想編寫自己的代碼文件以瞭解它是如何工作的。除了代碼之外,我需要的是對它必須做什麼以及如何編譯/鏈接以實現它的一點幫助。 如果您知道任何有用的鏈接,也非常感激。

我的疑惑是:
如何編譯/鏈接創建從我的代碼的最後文件和C運行時?我是否必須從crt0.o調用主函數(使用extern指令)?當我執行g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe時,出現「* undefined reference to __main *」錯誤。在crt0.o文件中定義了主函數嗎?奇怪的是,如果我通過int start更改int main,我不會收到任何錯誤。那是什麼意思?
2.哪些是crt0必須包含的基本操作(如獲取命令行參數,調用main)?
3.我的代碼文件是CPP,crt0是C文件內的一個程序集(用GCC編譯)。我將發佈一些「frankencode」我設法從片,我發現創建和部分地理解爲:

// crt0.c 
__asm(".section .text\n" 
".global _start\n" 
"_start:\n" 
"mov $0, %ebp\n" 
"push %ebp\n" 
"mov %esp, %ebp\n" 
"push %esi\n" 
"push %edi\n" 
"call _init\n" 
"pop %edi\n" 
"pop %esi\n" 
"call main\n" 
"movl %eax, %edi\n" 
"call exit\n" 
".section .init\n" 
".global _init\n" 
"_init:\n" 
"push %ebp\n" 
"mov %esp, %ebp\n" 
".section .fini\n" 
".global _fini\n" 
"_fini:\n" 
"push %ebp\n" 
"mov %esp, %ebp\n"); 

4)所以,在這個文件中,我做了一些調用初始化函數。 init和fini函數已經被創建(它們看起來像簡單的構造函數和析構函數,我不知道)還有一個主函數,我不知道如何與.cpp main函數相關。我的意思是,我應該導入它嗎?主函數和退出函數都會出現undefined reference錯誤。
5.)必須c0具有特定的格式或包含特定的功能,以便系統找到它的開始?

好了,我沒有看到它,使一個小信息crt0困難,使編譯器將其連接到可執行文件,但也有一些事情我不能正確地看。我希望有人能夠幫助我融合所有這些。由於

+0

什麼是您的實際目標這裏? – 2013-02-23 16:46:06

+0

C語言創建一個簡單的信息crt0,鏈接它針對C++文件,使該文件只運行這一點。 – ali 2013-02-23 16:48:58

+1

是的,但你比如希望能夠做到'COUT <<「世界,你好!\ n」','叫蘭特()',調用與靜態存儲時間'new' /'delete'或使用對象,等等等等?這些都是在啓動時準備好的。 – 2013-02-23 16:51:06

回答

1

我沒有Windows機器上測試,但是這應該是你所需要的基本位:

#// crt0.c 
__asm(".section .text\n" 
".global _start\n" 
"_start:\n" 
"mov $0, %ebp\n" 
"push %ebp\n" 
"mov %esp, %ebp\n" 
"call main\n" 
"pop %ebp\n" 
"ret\n"); 

編輯:空__main

__asm(".global __main\n" 
     "__main:\n" 
     "ret\n"); 
+0

是的,但我得到「未定義參考到__main」當我編譯包含的主要功能的CPP。所以,我不知道如何讓編譯器知道從哪裏找到我從這段代碼中調用的main。 – ali 2013-02-23 17:05:20

+0

如果你反彙編你的'main.o',是否有任何機會調用'__main'?我認爲MingW會這樣稱呼一些構造函數和這些東西。在這種情況下,你必須添加我在上面編輯過的代碼[註釋中的代碼轉到...] – 2013-02-23 17:10:14

相關問題