源文件是如何通過編譯器換成可執(zhí)行文件的?
可執(zhí)行文件被加載到內(nèi)存后是如何運(yùn)行的?
程序運(yùn)行是內(nèi)存上的棧和堆是如何進(jìn)行的?
計(jì)算機(jī)只能運(yùn)行本地代碼(機(jī)器語言代碼)
編譯器負(fù)責(zé)轉(zhuǎn)換源代碼
讀入的源代碼還要經(jīng)過語法解析、句法解析、語義解析等,才能生成本地代碼
編譯器不僅和編程語言的種類有關(guān),和CPU的類型也是相關(guān)的。

僅靠編譯是無法得到可執(zhí)行文件的
本地文件是無法直接運(yùn)行的,為了得到可以運(yùn)行的EXE文件,編譯之后還需要進(jìn)行“鏈接”處理。
把多個目標(biāo)文件結(jié)合,生成1個EXE文件的處理就是鏈接,運(yùn)行連接的程序就稱這鏈接器。
啟動及庫文件
c0w32.obj 這個目標(biāo)文件記述的是同所有程序起始位置相結(jié)合的處理內(nèi)容,程序的啟動。
庫文件指的是把多個目標(biāo)文件集成保存到一個文件中的形式。鏈接器指定庫文件后,就會從中把需要的目標(biāo)文件抽取出來,并同其他目標(biāo)文件結(jié)合生成EXE文件。
不是通過源代碼形式而是通過庫文件形式和編譯器一起提供的的函數(shù)稱為標(biāo)準(zhǔn)函數(shù)。
DLL文件及導(dǎo)入庫
windows 以函數(shù)的形式為應(yīng)用提供了各種功能。這些形式的函數(shù)稱為API,并不是C語言的標(biāo)準(zhǔn)函數(shù)。
API的目標(biāo)文件,并不是存儲在通常的庫文件中,而存儲在名為DLL文件的特殊庫文件中,這樣的庫文件稱之為導(dǎo)入庫。DLL文件是程序運(yùn)行時動態(tài)結(jié)合的文件。(個人覺得可以理解為系統(tǒng)文件)
可執(zhí)行文件運(yùn)行時的必要條件
每次運(yùn)行是,程序內(nèi)的變量及函數(shù)被分配到的內(nèi)存地址是不同的。那么在EXE文件中,變量和函數(shù)的內(nèi)存地址的值,是如何來表示的呢?
答案就是EXE文件中給變量及函數(shù)分配了虛擬的內(nèi)存地址。在程序運(yùn)行時,虛擬的內(nèi)存地址會轉(zhuǎn)換成實(shí)際的內(nèi)存地址。鏈接器會在EXE文件的開頭,追加轉(zhuǎn)換內(nèi)存地址所需的必要信息。這個信息稱為再配置信息。這個再配置信息,變成為了變量和函數(shù)的相對地址。
程序加載時會生成棧和堆
當(dāng)程序加載到內(nèi)存后,除此之外還會額外生成兩個組,那就棧和堆。棧是用來存儲函數(shù)內(nèi)部臨時使用的變量(局部變量),以及函數(shù)調(diào)用時所用的參數(shù)的內(nèi)存區(qū)域。堆是用來存儲程序運(yùn)行時的任意數(shù)據(jù)及對象的內(nèi)存領(lǐng)域。
因此,內(nèi)存中的程序,就是由用于變量的內(nèi)存空間,用于函數(shù)的內(nèi)存空間,用于棧的內(nèi)存空間,用于堆的內(nèi)存空間。當(dāng)然加載操作系統(tǒng)的內(nèi)存空間是另外一回事了。
棧中對數(shù)據(jù)進(jìn)行存儲和舍棄的代碼,是由編譯器自動生成的,不需要程序員參與。每當(dāng)函數(shù)調(diào)用時會得到申請分配,函數(shù)處理完成后自動釋放。堆則要根據(jù)程序員編寫的程序,來明確進(jìn)行申請分配或釋放。
直接今天才對內(nèi)存管理有了個基本清晰的了解,總算找到了一本說得清楚的書了。不過還是有點(diǎn)沒太理解堆中的任意數(shù)據(jù)指的是?還有類和對象在內(nèi)存的處理方式。