I’m currently facing new problem with operators. Using following code, I want to make output that would be same as when using if ... else pair in C#.
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();
My questions are:
- How can I get the address of an instruction to pass it as a parameter for branch opcodes?
- Is there any difference between
BRandBR_S,BrtrueandBrtrue_S,BrfalseandBrfalse_Sand similar instructions?
Thanks.
ILGenerator.ILOffsetgives you the current offset in the IL stream, if that’s what you want. You can useDefineLabelandMarkLabel, too, as goric suggested.The only difference between
brtrue.sandbrtrueis thatbrtrue.sis the short version ofbrtrue.brtrueuses a 4-byte offset andbrtrue.suses a 1-byte offset. The same applies forbrfalseandbrfalse.s(andbr/br.s).Those are not the only short versions of an IL instruction, there are also other short instructions, like
ldc.i4.0–ldc.i4.8for loading integers. Those are mainly useful for generating smaller binaries, but i don’t think there is a big difference otherwise.