我现在面临着与运营商的新问题。使用下面的代码,我希望生成的输出与在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();

我的问题是:
如何获取指令的地址作为分支操作码的参数传递?
BRBR_SBrtrueBrtrue_SBrfalseBrfalse_S以及类似指令之间有什么区别吗?
谢谢。

最佳答案

ILGenerator.ILOffset为您提供IL流中的当前偏移量(如果您需要的话)。你可以使用DefineLabelMarkLabel,就像Gric建议的那样。
brtrue.sbrtrue之间的唯一区别是brtrue.sbrtrue的缩写。brtrue使用4字节偏移量,brtrue.s使用1字节偏移量。这同样适用于brfalsebrfalse.s(和br/br.s)。
这些不是IL指令的唯一短版本,还有其他短指令,如用于加载整数的ldc.i4.0-ldc.i4.8。它们主要用于生成较小的二进制文件,但我认为其他方面没有太大区别。

07-26 04:35