我回來了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困難,使編譯器將其連接到可執行文件,但也有一些事情我不能正確地看。我希望有人能夠幫助我融合所有這些。由於
什麼是您的實際目標這裏? – 2013-02-23 16:46:06
C語言創建一個簡單的信息crt0,鏈接它針對C++文件,使該文件只運行這一點。 – ali 2013-02-23 16:48:58
是的,但你比如希望能夠做到'COUT <<「世界,你好!\ n」','叫蘭特()',調用與靜態存儲時間'new' /'delete'或使用對象,等等等等?這些都是在啓動時準備好的。 – 2013-02-23 16:51:06