程序集什麼玩意?我知道其表現形式為dll和exe,但是exe不是直接執行的文件嗎?而dll只是類庫,供exe調用代碼?

百度百科說,程序集是經由編譯器編譯得到的,供CLR進一步編譯執行的那個中間產物,在WINDOWS系統中,它一般表現為·dll或者是·exe的格式,但是要注意,它們跟普通意義上的WIN32可執行程序是完全不同的東西,程序集必須依靠CLR才能順利執行。
exe是程序集的表現形式之一,exe不是已經編譯成機器碼了,可以讓計算機直接運行了,那上面為什麼還說它是中間碼,供clr進一步編譯???


題主說的是.NET Assembly(程序集)對吧。知乎沒有「.NET」這個標籤還真是惱人,只有「Dotnet」標籤…

言歸正傳,.NET Assembly雖然後綴名是.exe和.dll,文件格式確實也跟普通Win32應用程序一樣是PE(Portable Executable)格式,但其內容不一樣。

普通Win32應用的PE文件里,PE格式的代碼段里的代碼就是程序的主要代碼了,是以平台相關的機器碼形式存儲的;
而對.NET Assembly而言,其代碼主體是以MSIL(或者叫CIL)的中間代碼形式存儲在PE格式的「資源」部分而不是在代碼部分;其PE格式的代碼段里只包含一小塊「樁程序」(stub),負責將程序控制權交給CLR去繼續執行該assembly里的MSIL代碼。

也就是說,.exe後綴的.NET Assembly的PE格式代碼段里其實只有這樣一個函數調用:

_CorExeMain(...)

.dll後綴的則是:

_CorDllMain(...)

通過調用CLR的入口函數把控制權交給CLR。

不過從Windows XP開始,Windows自身的loader能夠識別出.NET Assembly,從而直接啟動CLR去執行該assembly而不需要執行上面說的stub代碼。這stub代碼主要是為了兼容更老版本的Windows用的。
放個傳送門:Anatomy of a .NET Assembly


exe和dll的物理存儲結構是非常相似的,都是PE格式,區別在於exe多了一個程序入口。

這就好一個類有無main方法的區別。


推薦閱讀:

TAG:NET | 編譯 | CLR | dll | exe |