gpt4 book ai didi

c# - Mono.Cecil 中的 If/else 和 while 分支

转载 作者:太空宇宙 更新时间:2023-11-03 14:57:39 26 4
gpt4 key购买 nike

据我所知,Cecil 不支持 DefineLabelMarkLabel。在使用 if-else 和 while 分支时,可以使用哪些替代方法(例如生成 Nop 操作码)来替换标签?

例如:

public void Run(bool someParam)
{
int someInt = 0;
while (someParam)
{
someInt = someInt + 1;
if (someInt == 10) someParam = false;
System.Console.WriteLine(someInt);
}
}

将具有以下反编译的 Reflection.Emit 代码:

Label whileLabel = gen.DefineLabel();
Label label1 = gen.DefineLabel();
Label label2 = gen.DefineLabel();
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Br_S,label1);
gen.MarkLabel(whileLabel);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Add);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ldc_I4_S,10);
gen.Emit(OpCodes.Ceq);
gen.Emit(OpCodes.Stloc_1);
gen.Emit(OpCodes.Ldloc_1);
gen.Emit(OpCodes.Brfalse_S,label2);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Starg_S,1);
gen.MarkLabel(label2);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Call,writeLineMethod);
gen.MarkLabel(label1);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Stloc_2);
gen.Emit(OpCodes.Ldloc_2);
gen.Emit(OpCodes.Brtrue_S,whileLabel);
gen.Emit(OpCodes.Ret);

在 Cecil 中如何“标记”标签?

最佳答案

基本上你在创建跳转时传递了目标指令,比如:

using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using System;
using System.Linq;
using BindingFlags = System.Reflection.BindingFlags;

using Cecilifier.Runtime;

public class SnippetRunner
{
public static void Main(string[] args)
{
var assembly = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition("name", Version.Parse("1.0.0.0")), "moduleName", ModuleKind.Dll);
var t1 = new TypeDefinition("", "Foo", TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.NotPublic, assembly.MainModule.TypeSystem.Object);
assembly.MainModule.Types.Add(t1);
t1.BaseType = assembly.MainModule.TypeSystem.Object;
var Foo_ctor_ = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, assembly.MainModule.TypeSystem.Void);
t1.Methods.Add(Foo_ctor_);
var il1 = Foo_ctor_.Body.GetILProcessor();
var Ldarg_02 = il1.Create(OpCodes.Ldarg_0);
il1.Append(Ldarg_02);
var Call3 = il1.Create(OpCodes.Call, assembly.MainModule.ImportReference(TypeHelpers.DefaultCtorFor(t1.BaseType)));
il1.Append(Call3);
var Ret4 = il1.Create(OpCodes.Ret);
il1.Append(Ret4);

var Foo_F_int32 = new MethodDefinition("F", MethodAttributes.Private | MethodAttributes.HideBySig, assembly.MainModule.TypeSystem.Void);
t1.Methods.Add(Foo_F_int32);
var il_Foo_F_int32 = Foo_F_int32.Body.GetILProcessor();
var x5 = new ParameterDefinition("x", ParameterAttributes.None, assembly.MainModule.TypeSystem.Int32);
Foo_F_int32.Parameters.Add(x5);
// if (x < 10)
var Ldarg_16 = il_Foo_F_int32.Create(OpCodes.Ldarg_1);
il_Foo_F_int32.Append(Ldarg_16);
var Ldc_I47 = il_Foo_F_int32.Create(OpCodes.Ldc_I4, 10);
il_Foo_F_int32.Append(Ldc_I47);
il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Clt));
var esp8 = il_Foo_F_int32.Create(OpCodes.Nop);
il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Brfalse, esp8));
//if body

// x = x + 1;
var Ldarg_19 = il_Foo_F_int32.Create(OpCodes.Ldarg_1);
il_Foo_F_int32.Append(Ldarg_19);
var Ldc_I410 = il_Foo_F_int32.Create(OpCodes.Ldc_I4, 1);
il_Foo_F_int32.Append(Ldc_I410);
il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Add));
var Starg_S11 = il_Foo_F_int32.Create(OpCodes.Starg_S, x5);
il_Foo_F_int32.Append(Starg_S11);
var ese12 = il_Foo_F_int32.Create(OpCodes.Nop);
il_Foo_F_int32.Append(esp8);
il_Foo_F_int32.Append(ese12);
Foo_F_int32.Body.OptimizeMacros();
var Ret13 = il_Foo_F_int32.Create(OpCodes.Ret);
il_Foo_F_int32.Append(Ret13);

assembly.Write(args[0]);
}
}

顺便说一下,上面的代码是用这个工具(https://cecilifier.me)生成的(可以帮助你了解Mono.Cecil),代码如下:

class Foo
{
void F(int x)
{
if (x < 10)
{
x = x + 1;
}
}
}

关于c# - Mono.Cecil 中的 If/else 和 while 分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48153873/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com