2009-11-12 57 views
0

我在x86程序集上關注this tutorial。到目前爲止,每個示例都使用作者稱之爲「C驅動程序」的程序,並使用程序集模塊進行編譯,以獲得某些「初始化」。例如:x86彙編:主要序言和結語是什麼?

int main(void) { 
    int ret = asm_main(); 
    return ret; 
} 

然後使用C調用約定正常寫入asm_main函數。我想知道C編譯器生成的所需初始化究竟是什麼,以及是否可以以便攜方式完成。

信息:我在Windows XP 32bit盒子上,使用NASM彙編器和mingw32-gcc進行鏈接。

回答

5

初始化不是由c編譯器生成的,它是c庫的一部分(這使得爲每個操作系統/處理器定製操作變得更容易)。

有問題的代碼通常在windows/unixy系統上非常簡單 - 通常會執行一些庫初始化(打開STDIN,STDOUT,STDERR,設置時區等),設置環境,處理命令行以傳遞給主要;捕獲從main()返回並調用退出等。

大多數c庫中的啓動代碼位於名爲crt0.c,crt1.c或類似文件(crt = c運行時)的文件中。

在更原始或裸露的系統上,它也會設置堆棧和其他寄存器並清除BSS數據區 - 在這種情況下,它通常是彙編器(通常爲crt0.S)。

這裏是BSD的C啓動代碼的鏈接 - link text

而對於的MinGW的啓動代碼窗口中crt1.c這裏 - http://mingw.cvs.sourceforge.net/viewvc/mingw/runtime/

+2

在一個C項目中,您所討論的所有這些設置都是在main調用之前自動處理的(並且在主返回後自動退出事件)。 現在你可能會問,「什麼是C項目?」。那麼,這有點棘手的問題,但基本上,如果你有一個「主」功能和鏈接與libc(-lc)你正在作爲一個C項目工作,即使你的代碼中的每個功能都是用asm編寫的。 –

0

你可以寫你的主要裝配,如果你想。但是很多人都希望將調試語句放在main中,並且在C中比在asm中更容易。

如果您在asm中編寫main,您可能不得不處理main實際被調用的_main或使用替代調用約定(尤其是在Windows下)或其他奇怪的事情,例如C編譯器在生成代碼時自動處理的其他奇怪事情一個名爲「main」的函數。這樣做,所以你不必這樣做。

0

在調用main()之前,必須初始化堆棧,寄存器和程序的文件段(data,rodata,bss等)。 C運行時庫(CRT)提供了這個初始化。

CRT還提供了在每個函數被調用之前和之後執行的序言和尾聲代碼。序言和epilogue代碼更新堆棧和幀指針。