当前位置:  开发笔记 > 编程语言 > 正文

为什么C# - > CIL在每条指令上都有标签?

如何解决《为什么C#->CIL在每条指令上都有标签?》经验,为你挑选了2个好方法。

在已编译的C#程序上使用ILDASM.exe时,它会显示方法中的每条指令都有一个标签.

例如:

IL_0001:  ldc.i4.4
IL_0002:  stloc.0
IL_0003:  ldc.r8     12.34
IL_000c:  stloc.1
IL_000d:  ldc.r8     3.1415926535897931
IL_0016:  stloc.2
IL_0017:  ldstr      "Ehsan"
IL_001c:  stloc.3
IL_001d:  ret

为什么是这样?这样做效率不高或者CIL编译器本身是否优化这些标签?



1> Wiktor Zychl..:

编译的CIL中不存在标签.它们是为了方便您在反汇编代码中显示的.

这些特定标签对应于指令偏移,而手工代码没有这样的限制(标签可以是任意字符串).


可能更容易确保给每个指令一个标签,而不是跟踪哪些标签需要发出并只发出那些标签.

2> svick..:

在编译的IL中,没有标签.相反,跳转指令使用从以下指令开始的相对偏移量.

例如,考虑一下这个简单的C#函数:

public static bool IsZero(int n)
{
    if (n == 0)
        return true;
    return false;
}

在IL中,您可以这样写:

.method public hidebysig static bool IsZero(int32 n) cil managed
{
    ldarg.0     
    brtrue.s label
    ldc.i4.1    
    ret         
label:
    ldc.i4.0    
    ret   
}

如果你使用ilasm编译它然后使用ildasm反编译它,并启用"显示字节",你会得到:

.method public hidebysig static bool  IsZero(int32 n) cil managed
// SIG: 00 01 02 08
{
  // Method begins at RVA 0x2052
  // Code size       7 (0x7)
  .maxstack  8
  IL_0000:  /* 02   |                  */ ldarg.0
  IL_0001:  /* 2D   | 02               */ brtrue.s   IL_0005
  IL_0003:  /* 17   |                  */ ldc.i4.1
  IL_0004:  /* 2A   |                  */ ret
  IL_0005:  /* 16   |                  */ ldc.i4.0
  IL_0006:  /* 2A   |                  */ ret
} // end of method Program::IsZero

注意标签不以任何方式表示在字节中(显示在注释中).而brtrue.s label原始IL的内容在这里显示为brtrue.s IL_0005字节所在的位置2D 02.2D是编译形式brtrue.s,02是相对偏移量.由于以下指令以绝对偏移3开始,因此目标处于绝对偏移3 + 2 = 5.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有