前言: eshusheng 目前正在学习 C# 及 ASP.NET ,主要参考书目为 Inside C# ,Second Edition (我们以下的例子主要来源于 Inside C# ,Second Edition ,我可不是这本书的托,只是它的实例比较多而已)和 C# 高级编程以及 MSDN 。书虽看得快,却没有任何效果,猛然想起多年前老师教导之读书应该“由厚到薄,有薄到厚”,于是写下学习笔记,欲先实现“由厚到薄”的目的。希望能给比我更初学者以帮助,更望得到高手的指正。
闲话少叙,让我们从开始吧。既然是让书变薄的过程,我不希望从最基础讲起,但我想我们会对实例更感兴趣。
由于需要多次用到命令行工具,首先我们来配置我们的系统。如果你安装了 VS.NET ,则无需另外配置,直接在 VS.NET 程序组的工具中单击 VS.NET 命令行提示即可运行 csc 等学习 C# 的常用工具。有一点例外,在 VS.NET 7.0 ( VS.NET 7.1 即 VS.NET2003 没有这个问题)中,直接点击 VS.NET 命令行提示时,命令可以执行,但是 MS-DOS 窗口没有滚动条,看不出完全的效果。所以如果你的系统是 VS.NET 7.0 则需要做如下的设置:(注,由于没有多台机器做这个简单的测试,不知道是操作系统的问题还是 VS.NET 的问题)
(以下均以 WIN2003 SERVER 和 VS.NET2003 为例,其他系统类似)
点击控制面板的系统-高级-环境变量-系统变量中选 Path ,加入以下几行:
;C:\Program Files\Microsoft Visual Studio .NET\Vc7\bin;
C:\Program Files\Common Files\Microsoft Shared\VSA\7.1\VsaEnv;
C:\Program Files\Microsoft Visual Studio
.NET\FrameworkSDK\Bin;c:\winnt\microsoft.net\framework\v1.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 mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 1:0:5000:0
}
.assembly HelloWorldConsole
{
// --- 下列自定义属性会自动添加,不要取消注释 -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.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.Object::.ctor() // 调用 System.Object 的 构造函数 ctor
IL_0006: ret // 控制返回给正在进行调用的方法,相当于 return
} // end of method HelloWorldConsoleApp::.ctor
首先说明的是,这就是传说中的 MSIL (微软中间语言)代码。我们分析一下。
第一行描叙了方法的属性特征。 cil managed 表示托管代码(需要在 .NET 框架下运行的代码)
.ctor() 表示这是构造函数。
其余几行解释添加在代码之后。
最后一个 Main: void() ,表示 Main 方法的实现。和上面类似。不多解释。
更多的反汇编程序的用法,请参见MSDN。
PS :写学习笔记也是很累的。