微軟的 .NET 虛擬機平台

受到昇陽 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 平台的工具匯整於表格 9.2中,以比較這些平台與工具之異同。透過這樣的比較,可以幫助讀者找到每個平台開發工具並有效的加以運用。有關 GNU 工具的用法,在本書前面章節的實務案例中已經有詳細的說明,而 Java 工具的用法也已於9.4.1節中說明過了,在本節中,我們會將焦點放在 .NET平台的工具上。

表格 9.2 C語言, Java 與.NET 的工具對照表

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

由於 .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命令題示字元』這個命令列環境後開始使用這些工具。表格 9.3中列出了這些工具以及其用法,以供讀者參考。

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

工具類型 指令 用法
編譯器 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

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

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

檔案 HelloWorld.cs (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 反組譯成組合語言檔,範例 9.8顯示了反組譯的指令與結果,該指令會反組譯出兩個檔案,其中的 HelloWorld.cil 為 .NET 平台上的 Common Intermediate Language 組合語言,另一個則是 XML 語法的 HelloWorld.res 資源檔,讀者透過 ildasm 這個反組器器,觀察其組合語言語法。

範例 9.8 利用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..WrapNonEx
                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
  .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 這個指令去組譯該反組譯後的組合語言檔,其執行結果如範例 9.9所示。

範例 9.9 利用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!

目前,我們已經介紹了微軟 .NET 工具的命令列部分,但實際上很少人會直接使用命令列的方式開發 .NET 上的程式,通常會使用微軟的整合開發工具 Visual Studio 進行開發,Visual Studio整合了大部分的命令列工具,並且包含了微軟 Pocket PC 與智慧型手機 (SmartPhone) 等裝置的模擬器,可以讓使用者在個人電腦上開發手機程式。圖 9.10顯示了在 Visual Studio 中開發智慧型手機程式的整合環境,

SmartPhoneEmulator.jpg

圖 9.10 微軟 Visual Studio 中的智慧型手機模擬器

在目前的手機產業當中,系統軟體的重要性目前越來越強,傳統的手機製造公司往往無法應付這種局面,以致於讓專業的軟體公司找到切入產業的機會。微軟公司挾著個人電腦軟體霸主的地位,利用 SmartPhone 切入這個市場,而蘋果的 iPhone 則直接整合軟硬體形成單一系統,後來 Google 則利用開放原始碼社群的力量,推出了 Android手機作業平台。這些動作對傳統的手機製造商,像是 Nokia, Motorola 造成相當大的威脅,但也造成了新的機會,宏達電 HTC近年來就不斷利用微軟與 Google 侵入高階手機市場,於是得到快速的發展。系統程式設計師在手機產業中的重要性逐漸由配角地位變成主角,手機產業的重心也從硬體移到軟體上,能夠善用各個主要平台的系統程式設計師,將會是手機產業中熾手可熱的人物。

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