微軟的 .NET 平台與 CLR 虛擬機

微軟程式環境

簡介

系統工具

VisualStudio

ml 組譯器

cl 編譯器

csc 編譯器

vbc 編譯器

IIS 伺服器

訊息

相關網站

參考文獻

最新修改

簡體版

English

簡介

受到昇陽 Java 的 JVM虛擬機之影響,讓微軟也開始投入虛擬機的領域,微軟 .NET 平台所使用的虛擬機,稱為Common Lanugage Runtime (CLR)。.NET平台所採用的中間碼格式,原本稱為MSIL (Microsoft Intermediate Language),現在改稱為CIL (Common Intermediate Language)。

在微軟的 Visual Studio Professional 軟體中,附有該虛擬機的相關開發工具,包含組譯器 ilasm、連結器 al、C# 編譯器 csc、反組譯器 ildasm、專案編譯器 nmake 等,這些開發工具的設計方式與GNU工具相當類似,只是其目標平台不再是像IA32等特定的電腦平台,而是CLR虛擬機的平台。

我們特別將 GNU, Java 與 .NET 平台的工具匯整於表格 1 中,以比較這些平台與工具之異同。透過這樣的比較,可以幫助讀者找到每個平台開發工具並有效的加以運用。

工具類型 GNU工具 (C) Java 工具 .NET平台
編譯器 gcc javac csc (C#), vbc (VB)
組譯器 as java ilasm
反組譯 objdump javap ildasm
連結器 ld al
符號表列印 nm jmap
專案編譯 make nmake

表格 1. GNU C, Java 與 .NET 的工具對照表

由於 .NET 平台的主要開發語言較多,不像 Java 採取單一語言的路線,因此具有數種常用的編譯器,像是 C# 的 csc 編譯器、Visual Basic 的 vbc 編譯器、J#的 jsc 編譯器等。在組譯與連結工具方面,ilasm 組譯器、ildasm反組譯器、al連結器等都是 .NET平台中常見的工具,這些工具通常放在像C:\WINDOWS\Microsoft.NET\Framework\v3.5這樣的資料夾當中,如果您有安裝 Visual Studio Professional 2008,您可以啟動像『開始/Microsoft Visual Studio 2008/Visual Studio Tools/Visual Studio 2008命令題示字元』這個命令列環境後開始使用這些工具。表格 2 中列出了這些工具以及其用法,以供讀者參考。

工具類型 指令 用法
編譯器 csc csc foo.cs /r:bar.dll /win32res:foo.res
csc foo.cs /debug /define:TEMP
組譯器 ilasm ilasm b.asm
反組譯 ildasm ildasm b.dll /out=b.asm
連結器 al al /out:c.dll a.netmodule b.netmodule

表格 2 .NET平台中的工具列表

為了體驗 .NET平台中程式開發工具的用法,首先我們撰寫了HelloWorld.cs 這個簡單的 C# 程式,然後利用 csc 工具進行編譯,此時會產生一個 HelloWorld.exe 的執行檔,接著打入 HelloWorld 這個指令以執行 HelloWorld.exe 即可看到 Hello World! 字樣,這代表該程式的編譯與執行結果正常。

範例 1 C# 的程式與編譯過程

// C# 範例程式
using System;
class HelloWorld {
  public static void Main(string[] args) {
    Console.WriteLine("Hello World!");
  }
}

編譯與執行過程
D:\ch10>csc HelloWorld.cs

D:\ch10>HelloWorld
Hello World!

接著,我們可以利用 ildasm 將 HelloWorld.exe 反組譯成組合語言檔,範例 2 顯示了反組譯的指令與結果,該指令會反組譯出兩個檔案,其中的 HelloWorld.cil 為 .NET 平台上的 Common Intermediate Language 組合語言,另一個則是 XML 語法的 HelloWorld.res 資源檔,讀者透過 ildasm 這個反組器器,觀察其組合語言語法。

範例 2 利用ildasm將 .NET 的執行檔反組譯

指令:ildasm HelloWorld.exe /out=HelloWorld.cil
檔案 HelloWorld.cil 反組譯檔
//  Microsoft (R) .NET Framework IL Disassembler.  Version 3.5.21022.8
//  Copyright (c) Microsoft Corporation.  All rights reserved.
// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly HelloWorld
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices
        .CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Runtime.CompilerServices
        .RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   
         // ....T..WrapNonExceptionThrows.  63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) 
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module HelloWorld.exe
// MVID: {140D9BBE-314D-432F-9BBB-228DB44FE68F}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x03040000

// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit HelloWorld
       extends [mscorlib]System.Object
{
  .method public hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // 程式碼大小       13 (0xd)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "Hello World!"
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  ret
  } // end of method HelloWorld::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // 程式碼大小       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method HelloWorld::.ctor
} // end of class HelloWorld
// =============================================================
// *********** 反組譯作業完成 ***********************
// 警告: 已建立 Win32 資源檔 HelloWorld.res
資源檔HelloWorld.res
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

如果我們利用 ilasm 去組譯 HelloWorld.cil 這個檔案,照理說應該會得到一模一樣的 HelloWorld.exe 檔案,於是筆者用 ilasm HelloWorld.cil 這個指令去組譯該反組譯後的組合語言檔,其執行結果如範例 3 所示。

範例 3 利用ilasm組譯 CIL組合語言

D:\ ch10>ilasm HelloWorld.cil

Microsoft (R) .NET Framework IL Assembler.  Version 2.0.50727.1433
Copyright (c) Microsoft Corporation.  All rights reserved.
Assembling 'HelloWorld.cil'  to EXE --> 'HelloWorld.exe'
Source file is ANSI

Assembled method HelloWorld::Main
Assembled method HelloWorld::.ctor
Creating PE file

Emitting classes:
Class 1:        HelloWorld

Emitting fields and methods:
Global
Class 1 Methods: 2;

Emitting events and properties:
Global
Class 1
Writing PE file
Operation completed successfully

D:\ch10>HelloWorld
Hello World!

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License