我现在面临着与运营商的新问题。使用下面的代码,我希望生成的输出与在c中使用if ... else
对时的输出相同。
var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
var g = method.GetILGenerator();
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Call, typeof(String).GetMethod("op_Equality", new Type[]{typeof(string), typeof(string)}));
g.Emit(OpCodes.Ldc_I4, 0);
g.Emit(OpCodes.Ceq);
g.Emit(OpCodes.Brtrue_S, );
var action = (Action)method.CreateDelegate(typeof(Action));
action();
Console.Read();
我的问题是:
如何获取指令的地址作为分支操作码的参数传递?
BR
和BR_S
、Brtrue
和Brtrue_S
、Brfalse
和Brfalse_S
以及类似指令之间有什么区别吗?谢谢。
最佳答案
ILGenerator.ILOffset
为您提供IL流中的当前偏移量(如果您需要的话)。你可以使用DefineLabel
和MarkLabel
,就像Gric建议的那样。brtrue.s
和brtrue
之间的唯一区别是brtrue.s
是brtrue
的缩写。brtrue
使用4字节偏移量,brtrue.s
使用1字节偏移量。这同样适用于brfalse
和brfalse.s
(和br
/br.s
)。
这些不是IL指令的唯一短版本,还有其他短指令,如用于加载整数的ldc.i4.0
-ldc.i4.8
。它们主要用于生成较小的二进制文件,但我认为其他方面没有太大区别。