【问题标题】:C#/.Net CIL - ldarga.s how to get index/argument (ldarga.s vs ldarga vs ldarga.0 opcode)?C#/.Net CIL - ldarga.s 如何获取索引/参数(ldarga.s vs ldarga vs ldarga.0 操作码)?
【发布时间】:2020-03-18 20:33:29
【问题描述】:

我正在尝试逐条解释 CIL 指令。我正在使用 Mono.Reflection 获取指令列表,我不知道如何解释“ldarga.s”

我知道“ldarga”-Load the argument address to the evaluation stack." 但是 'ldarga.s' 的参数/索引是什么,即加载/压栈? - 该指令位于 IL_0004 以下汇编程序列表下。

另一条指令“ldarg.0”(不带“a”)参数加载/将“第一个”压入堆栈,“ldarg.1”参数加载/压入堆栈的第二个 在另一个示例中,“ldloca.s”-“将指定索引处的局部变量的地址加载到评估堆栈中。”) 索引在指令操作数中。

这是我的代码 我在测试类中有函数“Funkcja1”

public int Funkcja1(int p1, string p2, ProcesTest p3)
    {
        var zmienalokaln1 = p1;
        var zmiennaLokaln2 = p2 + p1.ToString();
        Metoda1();
        var zmienna3 = zmienalokaln1 + zmiennaLokaln2;
        return zmienna + p1 + p2.Length + zmienna3.Length;
    }

函数汇编器(由 JetBrains dotPeek 生成):

.method public hidebysig instance int32
Funkcja1(
  int32 p1,
  string p2,
  class Cvl.VirtualMachine.Test.ProcesTest p3
) cil managed
{
.maxstack 2
.locals init (
  [0] int32 zmienalokaln1,
  [1] string zmiennaLokaln2,
  [2] string zmienna3,
  [3] int32 V_3
)

// [18 9 - 18 10]
IL_0000: nop

// [19 13 - 19 36]
IL_0001: ldarg.1      // p1
IL_0002: stloc.0      // zmienalokaln1

// [20 13 - 20 53]
IL_0003: ldarg.2      // p2
IL_0004: ldarga.s     p1
IL_0006: call         instance string [System.Runtime]System.Int32::ToString()
IL_000b: call         string [System.Runtime]System.String::Concat(string, string)
IL_0010: stloc.1      // zmiennaLokaln2

// [22 13 - 22 23]
IL_0011: ldarg.0      // this
IL_0012: call         instance void Cvl.VirtualMachine.Test.ProcesTest::Metoda1()
IL_0017: nop

// [24 13 - 24 59]
IL_0018: ldloca.s     zmienalokaln1
IL_001a: call         instance string [System.Runtime]System.Int32::ToString()
IL_001f: ldloc.1      // zmiennaLokaln2
IL_0020: call         string [System.Runtime]System.String::Concat(string, string)
IL_0025: stloc.2      // zmienna3

// [26 13 - 26 63]
IL_0026: ldarg.0      // this
IL_0027: ldfld        int32 Cvl.VirtualMachine.Test.ProcesTest::zmienna
IL_002c: ldarg.1      // p1
IL_002d: add
IL_002e: ldarg.2      // p2
IL_002f: callvirt     instance int32 [System.Runtime]System.String::get_Length()
IL_0034: add
IL_0035: ldloc.2      // zmienna3
IL_0036: callvirt     instance int32 [System.Runtime]System.String::get_Length()
IL_003b: add
IL_003c: stloc.3      // V_3
IL_003d: br.s         IL_003f

// [27 9 - 27 10]
IL_003f: ldloc.3      // V_3
IL_0040: ret

} // end of method ProcesTest::Funkcja1

来自 Mono.Reflection.Disassembler.GetInstructions(this MethodBase self)

操作数是'p1'

我需要以某种方式在函数参数列表中指定此参数('p1')的索引,在这种情况下等于 0(第一个参数)

【问题讨论】:

  • 不是0,是1。参数0是每个实例方法获取的隐藏的this参数。
  • @HansPassant - 真

标签: c# .net cil opcode mono.cecil


【解决方案1】:

ldarga.s 中的操作数可以通过System.Reflection.ParameterInfo

index = parameterInfo.Position;

if (instruction.Operand is System.Reflection.ParameterInfo parameterInfo)
{
   Index = parameterInfo.Position;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2012-10-07
    • 1970-01-01
    相关资源
    最近更新 更多