C#學習筆記一:深入HelloWorld內部 (轉)

worldblog發表於2007-08-16
C#學習筆記一:深入HelloWorld內部 (轉)[@more@]

前言:eshusheng目前正在學習及,主要參考書目為Ins C# ,Second Edition(我們以下的例子主要來源於Inside C# ,Second Edition,我可不是這本書的託,只是它的例項比較多而已)和C#高階以及MSDN。書雖看得快,卻沒有任何效果,猛然想起多年前老師教導之讀書應該“由厚到薄,有薄到厚”,於是寫下學習筆記,欲先實現“由厚到薄”的目的。希望能給比我更初學者以幫助,更望得到高手的指正。

:namespace prefix = o ns = "urn:schemas--com::office" />

閒話少敘,讓我們從開始吧。既然是讓書變薄的過程,我不希望從最基礎講起,但我想我們會對例項更感興趣。

由於需要多次用到命令列工具,首先我們來我們的。如果你了VS.NET,則無需另外配置,直接在VS.NET組的工具中單擊VS.NET命令列提示即可執行csc等學習C#的常用工具。有一點例外,在VS.NET 7.0(VS.NET 7.1即VS.NET沒有這個問題)中,直接點選VS.NET命令列提示時,命令可以,但是MS-DOS視窗沒有捲軸,看不出完全的效果。所以如果你的系統是VS.NET 7.0 則需要做如下的設定:(注,由於沒有多臺機器做這個簡單的測試,不知道是的問題還是VS.NET的問題)

(以下均以 SERVER和 VS.NET2003為例,其他系統類似)

點選控制皮膚的系統-高階-環境變數-系統變數中選Path,加入以下幾行:

;C:Program FilesMicrosoft Vc7in;

C:Program FilesCommon FilesMicrosoft SharedVSA7.1VsaEnv;

C:Program FilesMicrosoft Visual Studio

.NETSDKBin;c:winntmicrosoft.netframeworkv1.1.4322;

注:最後一個路徑根據你.NET安裝的路徑決定。倒數第二路徑“7.1”可根據VS.NET的版本改成“7.0”。

配置好了,開始我們第一個經典的helloworld程式吧。命名為:helloworldconsole.cs

namespace HelloWorld

{

 class HelloWorldConsoleApp

 {

  static void Main()

  {

  System.Console.WriteLine("Hello, World");

  }

 };

};

我特意在名稱空間和類的結束符後打了分號,大家很少會這麼做,但是必須說明一點的是,這個分號是可選的,並不是錯誤。

這個程式原本很簡單,我不打算解釋,我們現在深入到其中去。

首先我們用命令列編譯工具編譯源:csc helloworldconsole.cs

在命令列下輸入helloworldconsole即可看到效果。

為了檢視Helloworldconsole.exe內部資訊,我們需要用到.NET的反工具(ILDASM),在命令列下輸入ildasm,並開啟Helloworldconsole.exe,這時我們看到如下圖:

 

可以看到,Helloworldconsole.exe由MANIFEST(清單)、HelloWorld名稱空間和HelloWrldConsoleApp(Helloworldconsole應用程式類)構成。

我們雙擊清單得到如下資訊:

.assembly extern mrlib

{

  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )  // .zV.4..

  .ver 1:0:5000:0

}

.assembly HelloWorldConsole

{

  // --- 下列自定義屬性會自動新增,不要取消註釋 -------

  //  .custom instance void [mscorlib]System.Diagnostics.DegableAttribute::.ctor(bool,

  //  bool) = ( 01 00 00 01 00 00 )

  .hash algorithm 0x00008004

  .ver 0:0:0:0

}

.module HelloWorldConsole.exe

// MVID: {C5CE42D4-C4EA-42E4-8769-C996488F4357}

.imagebase 0x00400000

.subsystem 0x00000003

.file alignment 512

.corflags 0x00000001

// Image base: 0x07100000

我開始解釋這段程式碼。

.assembly extern mscorlib 表示引用一個外部裝配件mscorlib,這是一個系統配件。Publickeytoke顯示了引用mscorlib的實際密匙標記,ver顯然是其版本號。

第二段中“//”表示註釋資訊:custom instance void表示HelloWorldConsole這個裝配件是定製的不返回結果的例項(記得源程式中的static和 void嗎?),System.Diagnostics.DebuggableAttribute::.ctor(bool,bool) = ( 01 00 00 01 00 00 ) 表示編碼時不對程式碼進行(DebuggableAttribute屬性的結果),[mscorlib]表示這個屬性來自於mscorlib.dll。

第三段表示存放這個配件的物理檔名和相關資訊。

接下來我們看看.ctor: void()―――這是HelloWrldConsoleApp類的構造器。

.method public hidebysig specialname rtspecialname

  instance void  .ctor() cil managed

{

  // 程式碼大小  7 (0x7)

  .maxstack  1

  IL_0000:  ldarg.0  //將第一個引數壓入堆疊

  IL_0001:  call  instance void [mscorlib]System.::.ctor() //System.Object的構造ctor

  IL_0006:  ret  //控制返回給正在進行呼叫的方法,相當於return

} // end of method HelloWorldConsoleApp::.ctor

首先說明的是,這就是傳說中的MSIL(中間語言)程式碼。我們分析一下。

第一行描敘了方法的屬性特徵。cil managed表示託管程式碼(需要在.NET框架下執行的程式碼)

.ctor()表示這是建構函式。

其餘幾行解釋新增在程式碼之後。

最後一個Main: void(),表示Main方法的實現。和上面類似。不多解釋。

更多的反彙編程式的用法,請參見MSDN。

PS:寫學習筆記也是很累的。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-962477/,如需轉載,請註明出處,否則將追究法律責任。

相關文章