c# - 执行栈和线程的栈和局部变量列表是否引用不同的栈?

标签 c# stack clr il

值类型可能存储在线程的堆栈中,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 指的是哪个堆栈的方法?它是局部变量列表的大小吗?或插入执行堆栈的额外存储的最大大小?

在我看来执行堆栈是正确的堆栈,因为它只支持pushpop。局部变量列表支持从索引loadstore到索引。这与堆栈有什么关系?

更新:

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/

相关文章:

c# - 使用另一个字节列表/数组计算字节列表/数组中的出现次数

c - linux同进程下的线程如何分配stack或内存

c# - .Net Framework 上的 clr.dll 是什么,它有什么作用?

c# - 无法从 .cshtml 选项卡运行应用程序

c# - 过滤后如何将位置应用于节点

c# - 为什么我的 KendoGrid "update"参数在 Controller 中始终为空?

c - Stack 中的局部变量 -> C

ios - 约束后堆栈大小不正确

使用 C++/CLR dll 时 C# 应用程序崩溃

c# - 如何匹配 UDT T-SQL 和 C# CLR 类型?