值类型可能存储在线程的堆栈中,IL 在执行堆栈中运行(抽象概念)。
int y=0;
int a=0;
int b=0;
int x = y + (a - b);
IL_0001: ldc.i4.0
IL_0002: stloc.0 // y
IL_0003: ldc.i4.0
IL_0004: stloc.1 // a
IL_0005: ldc.i4.0
IL_0006: stloc.2 // b
IL_0007: ldloc.0 // y
IL_0008: ldloc.1 // a
IL_0009: ldloc.2 // b
IL_000A: sub
IL_000B: add
IL_000C: stloc.3 // x
现在 STLoc.0
从执行堆栈中弹出值并存储到局部变量列表中。因此,局部变量列表必须存储在执行堆栈以外的不同空间中。什么是局部变量列表?是线程的栈吗?
此外,.maxstack = 3
指的是哪个堆栈的方法?它是局部变量列表的大小吗?或插入执行堆栈的额外存储的最大大小?
在我看来执行堆栈是正确的堆栈,因为它只支持push
和pop
。局部变量列表支持从索引load
和store
到索引。这与堆栈有什么关系?
更新:
ECMA 335 I.12.3 机器状态清楚地回答了我的问题。
最佳答案
Lasse 的回答很好;我只想强调他的几点。
首先,C#被翻译成等价的IL程序,然后IL程序被翻译成等价的机器码程序。 IL 语言有评估堆栈的概念; 这纯粹是 IL 语言中的一个概念。所需要的只是抖动将该 IL 转换为具有相同最终结果的机器代码。没有任何要求抖动实际上使用“真实”堆栈只是因为 IL 程序被编写为使用“评估堆栈”。
基本上,IL 是一种采用极其简化的处理器的语言; IL 中没有“寄存器”,只有堆栈。在一个真正的处理器中当然有寄存器,因此 IL 的机器代码翻译当然不会盲目地遵循它对评估堆栈的使用;那将是愚蠢的。
“最大栈”指的是IL语言的“抽象”栈;它与机器代码中实际线程的堆栈没有特别的联系。
我已经写了很多关于“堆栈”的含义以及我们为什么使用 IL 的文章;如果您对这个主题感兴趣,您可能想查看它们:
关于c# - 执行栈和线程的栈和局部变量列表是否引用不同的栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16592299/