Sea*_*man 1 c# reflection il reflection.emit opcode
我正在尝试解析IL,以发出一种方法。我已经在string []中获得了方法的IL代码,其中每个字符串都是IL指令。我遍历此数组并使用ILGenerator添加OpCodes:
foreach (string ins in instructions) //string representations of IL
{
string opCode = ins.Split(':').ElementAt(1);
// other conditions omitted
if (opCode.Contains("br.s"))
{
Label targetInstruction = ilGenerator.DefineLabel();
ilGenerator.MarkLabel(targetInstruction);
ilGenerator.Emit(OpCodes.Br_S, targetInstruction);
}
Run Code Online (Sandbox Code Playgroud)
这是我需要重现的IL:
Source IL:
IL_0000: nop
IL_0001: ldstr "Hello, World!"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出:
Target IL:
IL_0000: nop
IL_0001: ldstr "Hello, World!"
IL_0006: stloc.0
IL_0007: br.s IL_0007 // this is wrong -- needs to point to IL_0009
IL_0009: ldloc.0
IL_000a: ret
Run Code Online (Sandbox Code Playgroud)
如您所见,br.s调用指向自身,这当然会导致无限循环。如何获得源代码中的以下说明?这与使用Reflection.Emit.Label有关,但是我不确定它是如何工作的。
编辑通过上面看到的IL就是这种简单方法,
public string HelloWorld()
{
return "Hello, World!";
}
Run Code Online (Sandbox Code Playgroud)
这段代码:
ilGenerator.MarkLabel(targetInstruction);
ilGenerator.Emit(OpCodes.Br_S, targetInstruction);
Run Code Online (Sandbox Code Playgroud)
清楚地说出“在此处标记标签”,然后将说明添加到标记标签的位置。
如果这不是您想要的,为什么要这样做?
MarkLabel将当前位置标记为标签的目标,这意味着您输出的下一条指令的位置。
在这种情况下,要获得“所需”,只需将这两行颠倒,在标记标签之前输出分支指令。
因为我不明白该分支指令的要点,所以在引号中加上了“您想要什么”。机器会很乐意自己全部“移动”到下一条指令,无需为此添加“分支到下一条指令”指令。
| 归档时间: |
|
| 查看次数: |
2981 次 |
| 最近记录: |