【问题标题】:While loop in IL - why stloc.0 and ldloc.0?IL 中的 While 循环 - 为什么是 stloc.0 和 ldloc.0?
【发布时间】:2010-04-09 12:27:51
【问题描述】:

我正在尝试了解 while 循环在 IL 中的外观。我已经编写了这个 C# 函数:

    static void Brackets()
    {
        while (memory[pointer] > 0)
        {
            // Snipped body of the while loop, as it's not important
        }
    } 

IL 看起来像这样:

.method private hidebysig static void  Brackets() cil managed
{
  // Code size       37 (0x25)
  .maxstack  2
  .locals init ([0] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  br.s       IL_0012
  IL_0003:  nop
  // Snipped body of the while loop, as it's not important
  IL_0011:  nop
  IL_0012:  ldsfld     uint8[] BFHelloWorldCSharp.Program::memory
  IL_0017:  ldsfld     int16 BFHelloWorldCSharp.Program::pointer
  IL_001c:  ldelem.u1
  IL_001d:  ldc.i4.0
  IL_001e:  cgt
  IL_0020:  stloc.0
  IL_0021:  ldloc.0
  IL_0022:  brtrue.s   IL_0003
  IL_0024:  ret
} // end of method Program::Brackets

除了cgt之后的部分之外,大部分情况都很简单。

我不明白的是本地[0]和stloc.0/ldloc.0。据我看,cgt将结果推入堆栈,stloc.0从堆栈中获取结果到局部变量中,ldloc.0再次将结果推入堆栈,brtrue.s从堆栈中读取。

这样做的目的是什么?这不能缩短为 cgt 后跟 brtrue.s 吗?

【问题讨论】:

  • 一个额外的金块给你,基于“因为它不重要”和你的推特提要......注意br*_sbr*之间的区别。 _s 变体使用较小的 相对 偏移量,如果位置不靠近,将不起作用(非_s 变体使用 absolute 没有“小”限制的偏移量)。因此,如果您的编译器无法(提前)预测正文的大小,请使用br* 而不是br*_s
  • @Marc 谢谢,正好遇到了这个问题:D 我的演示应用程序只有一条指令,因此编译器生成了 _s 变体,但我真正的编译器有更长的循环体。积极的副作用:我从那个“非法的单字节分支”异常中学到了一些东西:)
  • IIRC,如果您使用正确的方法,ILGenerator 足够聪明,可以针对当前情况发出正确的操作码。
  • @Nick - 来自(最近的)记忆我不这么认为。不过,我可能是错的。

标签: .net cil


【解决方案1】:

尝试使用优化进行编译。

【讨论】:

  • 这实际上“修复”了它 - 所以它只是为了调试/断点而存在吗?只是好奇为什么会首先生成它。
  • 我猜这两条相互抵消的指令来自编译器的不同部分。我绝对可以想象所有 while 循环最初都被转换为 nop(作为跳转目标).... ldloc. brtrue.s(nop 的地址)。如果您知道优化器将在下一次传递中删除不需要的 nop 等,这似乎足够理智。
【解决方案2】:

这是一个调试版本(来自nop)。所有的赌注都没有了,但为了简单起见,它看起来只是简单地引入了一个 bool 变量:

    goto testforexit;
body:
    ..
testforexit:
    bool tmp = memory[pointer] > 0;
    if(tmp) goto body;

启用优化的内置版本,应该会删除这些变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 2017-03-23
    • 1970-01-01
    • 2020-07-17
    • 2011-10-21
    • 1970-01-01
    • 2020-09-29
    相关资源
    最近更新 更多