上面錯誤信息的原因是,上面的程序有2個函 數,vijay和vijay1,每個函數都包括了.entrypoint偽指令。正如前面提到的那樣,這個指令指定了關於 那個函數會被首先執行。
因此,在功能上,它類似於C#中的Main函數。當C#代碼被轉換為IL代碼 時,在Main函數中包含的代碼會被轉換為IL中的函數中並包括.entrypoint偽指令。例如,如果在COBOL程 序中執行的第一個函數被稱為abc,那麼在IL中生成的代碼就會在這個函數中插入.entrypoint偽指令。
在常規的程序語言中,首先被執行的函數必須有一個特定的名稱,例如Main,但是在IL中,只需 要一個.entrypoint偽指令。因此,因為一個程序只能由一個開始點,所以在IL代碼中只允許一個函數包 括.entrypoint偽指令。
迫切地看到,沒有生成任何錯誤消息編號或說明,使得調試這個錯誤非常 困難。
a.il
.assembly mukhi {}
.method void vijay()
{
ret
.entrypoint
}
.entrypoint偽指令需要被定位為函數中的第一個指令或最後一個指令。它僅出現在函數 體中,從而將它的狀態宣布為第一個被執行的函數。偽指令不是程序集指令,甚至可以被放置在任何ret 指令之後。提醒你一下,ret表示函數代碼的結束。
a.il
.assembly mukhi {}
.method void vijay()
{
.entrypoint
call void System.Console::WriteLine()
ret
}
我們可能有一個用C#、VB.Net編寫的函數,但是在IL中執行這個函數的機制是相同的。 如下所示:
我們必須使用匯編指令調用。調用指令之後,按照給定的順序,為以下詳細內容:
函數的返回類型(void)
命名空間(System)
類 (Console)
函數名稱 (WriteLine())
函數被調用但不會生成任何輸出。因為,我們傳遞一個參數到WriteLine函數中。
a.il
.assembly mukhi {}
.method void vijay()
{
.entrypoint
call void System.Console::WriteLine(class System.String)
ret
}
上面的代碼有一處“閃光點”。當一個函數在IL中被調用時,除了它的返回 類型之外,被傳遞的參數的數據類型,也必須被指定。我們將Writeline設置為——希望得到 一個System.String類型作為參數,但是由於沒有字符串被傳遞到這個函數中,所以它會生成一個運行時 錯誤。
因此,在調用一個函數時,在IL和其他程序語言之間有一個明顯的區別。在IL中,當我們 調用一個函數,我們必須指定關於該函數我們所知道的任何內容,包括它的返回類型和它的參數的數據類 型。通過在運行期間進行恰當的檢查,保證了匯編器能夠在語法上驗證代碼的有效性。