gpt4 book ai didi

c# - .net 中的 IL 和堆栈实现?

转载 作者:可可西里 更新时间:2023-11-01 08:55:50 24 4
gpt4 key购买 nike

我写了一个简单的程序来检查 IL 的工作原理:

void Main()
{

int a=5;
int b=6;
if (a<b) Console.Write("333");
Console.ReadLine();
}

IL:

IL_0000:  ldc.i4.5    
IL_0001: stloc.0
IL_0002: ldc.i4.6
IL_0003: stloc.1
IL_0004: ldloc.0
IL_0005: ldloc.1
IL_0006: bge.s IL_0012
IL_0008: ldstr "333"
IL_000D: call System.Console.Write
IL_0012: call System.Console.ReadLine

我正在尝试了解实现效率:

  • 在第 1 行(IL 代码)它将值 5 压入堆栈(4 个字节,即 int32)

  • 在第 2 行(IL 代码),它从堆栈弹出到一个局部变量。

接下来的两行也是如此。

然后,它将这些局部变量加载到堆栈上,然后它计算 bge.s

问题 #1

他为什么要把局部变量加载到栈中?值已经在堆栈中。但他弹出它们是为了将它们放入局部变量中。这不是浪费吗?

我的意思是,为什么代码不能是这样的:

IL_0000:  ldc.i4.5
IL_0001: ldc.i4.6
IL_0002: bge.s IL_0004
IL_0003: ldstr "333"
IL_0004: call System.Console.Write
IL_0005: call System.Console.ReadLine

我的代码示例只有 5 行代码。 50,000,000 行代码呢? IL 会发出大量额外的代码

问题#2

查看代码地址:

enter image description here

  • IL_0009 地址在哪里?它不是应该是顺序的吗?

附注我在 + Release模式上设置了优化标志

最佳答案

我可以轻松回答第二个问题。指令是可变长度的。例如,ldstr "333"ldstr 的操作码(在地址 8)后跟表示字符串的数据(对用户字符串表中的字符串)。

与后面的 call 语句类似 - 您需要 call 操作码本身以及有关要调用的函数的信息。

将 4 或 6 等小值压入堆栈的指令没有额外数据的原因是这些值被编码到操作码本身。

参见 here用于说明和编码。

关于第一个问题,你可以看看this blog entry by Eric Lippert, one of the C# developers ,其中指出:

The /optimize flag does not change a huge amount of our emitting and generation logic. We try to always generate straightforward, verifiable code and then rely upon the jitter to do the heavy lifting of optimizations when it generates the real machine code.

关于c# - .net 中的 IL 和堆栈实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13777112/

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