2010-04-27 13 views
3

我想我可能會錯過一些重要的東西,但我似乎無法弄清楚如何用動態方法在IL中構造條件語句。我以前只是輕描淡寫地說過,但我現在需要擴展一些代碼。'if'block in IL

是否有一些我沒有找到的文檔(除CLI文檔外),還是有人有一些示例代碼?那太棒了。

乾杯,

+1

你是什麼意思「動態方法」?程序集中的if語句通常是一個跳轉操作。查找類似的IL命令。 – 2010-04-27 05:38:25

+0

好的,謝謝,我會。通過'動態方法'我的意思是例如:DynamicMethod dm = new DynamicMethod(「... – 2010-04-27 05:42:31

回答

4

根據您的確切代碼,各種分支指令是你的朋友。

這裏是

if(memory[pointer] > 0) goto IL_0002; 

在IL:

IL_001f: ldsfld  uint8[] BFHelloWorldCSharp.Program::memory 
IL_0024: ldsfld  int16 BFHelloWorldCSharp.Program::pointer 
IL_0029: ldelem.u1 
IL_002a: ldc.i4.0 
IL_002b: bgt  IL_0002 

你基本上推你要比較到堆棧中,然後調用bgt跳,你需要的值。

您可以檢查OpCodes Class以獲得有關IL命令的快速概述,例如brtrue/brfalse或beq。

我還建議在C#中編寫if命令,編譯它,並使用ILDASM或Reflector查看生成的IL。

+0

感謝那個鏈接到OpCodes類 - 我找不到任何鏈接發佈文章......煩人! – 2010-04-27 05:47:54

+0

@Luke如果你有興趣,我已經開始編寫一個.net編譯器系列(我選擇brainf..k作爲語言,因爲它很簡單)我沒有使用動態方法,但我確實使用了Reflection.Emit。關於實際編寫編譯器的文章(第6部分)應該在週末附近:http://www.stum.de/tag/brainfk/ – 2010-04-27 05:50:34

+0

@Luke我編譯器的源代碼在這裏:http://pastie.org/910946 - 雖然這是一段時間的聲明,但其行爲相似。也許它有幫助。 – 2010-04-27 05:52:23

1

這是怎麼一回事呢:

定義的標籤,如:

var skipProperty = il.DefineLabel(); 

打電話給你的條件:

il.Emit(OpCodes.Brtrue, skipProperty); 
在你想要跳過的地方

(如如果結束):

il.MarkLabel(skipProperty); 

因此,您需要創建一個標籤(您需要首先執行該操作,以便參考文件存在,稍後您可以調用'標記'將標籤放置到您想要的代碼中的實際位置)。 OpCodes.Brtrue只是link text文章中列出的許多條件操作之一(謝謝邁克爾