如何在.NET IL .maxstack指令工作?(How does the .NET IL .ma

2019-06-28 08:50发布

我想知道如何.maxstack真正发挥作用。 我知道这并不与你在声明类型的实际大小,但它们的数量做。 我的问题是:

  1. 这是否适用于只是为了功能,还是对所有我们所要求的功能呢?
  2. 即使它只是对功能进行.maxstack正在申报,你怎么知道什么是maxstack如果你有分支? 你去看看所有的“路径”,返回的最大可能值?
  3. 如果我将其设置为16,会发生什么,实际上有17个变量?
  4. 有没有太大的罚款,如果我将它设置为256?

Answer 1:

.maxstack是IL验证的一部分。 基本上.maxstack告诉JIT它需要保留该方法的最大堆栈大小。 例如, x = y + (a - b)转换为

(伪IL :)

1. Push y on the stack
2. Push a on the stack
3. Push b on the stack
4. Pop the last two items from the stack,
      substract them and
      push the result on the stack
5. Pop the last two items from the stack,
      add them and
      push the result on the stack
6. Store the last item on the stack in x and
      pop the last item from the stack

正如你所看到的,最多有3个项目堆栈中的每个时间上。 如果您想设置.maxstack为2(或以下)的这种方法,代码将无法运行。

此外,你不能有这样的事情,因为这将需要一个无限的堆栈大小:

1. Push x on the stack
2. Jump to step 1

要回答你的问题:

  1. 这是否适用于只是为了功能,还是对所有我们所要求的功能呢?

只是为了功能

  1. 即使它只是对功能进行.maxstack正在申报,你怎么知道什么是maxstack如果你有分支? 你去看看所有的“路径”,返回的最大可能值?

你去看看所有的路径,并返回可能的最大值

  1. 如果我将其设置为16,会发生什么,实际上有17个变量?

这是无关的变量的数目,看到拉塞·五卡尔森的回答

  1. 有没有太大的罚款,如果我将它设置为256?

似乎不是个好主意,但我不知道。

你真的要计算.maxstack自己呢? System.Reflection.Emit IIRC计算它。



Answer 2:

它无关的声明的变量数量 ,而是一切都与你需要多少价值,以便计算一些表达推栈在任何给定的时间。

例如,在下面的表达式,我会假设2个值需要被压入堆栈:

x = y + z;

这是无关的事实,即至少有3个变量存在,X,y和z,以及可能还有其他。

不幸的是,我不知道答案你的其他问题,我猜想的实验是要找到一些答案的一种方式。



Answer 3:

您可以参考以下内容,ECMA标准,以获得更好的理解:

void  msd(string a,
  string b,
  string c,
  string d,
  string e)
  {
  Console.WriteLine(a);
}

msd("a","b","c","d","e");

当我运行ildasm.exe我得到这个:

{
  .entrypoint
  // Code size       40 (0x28)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  nop
  IL_0002:  ldstr      "a"
  IL_0007:  ldstr      "b"
  IL_000c:  ldstr      "c"
  IL_0011:  ldstr      "d"
  IL_0016:  ldstr      "e"
  IL_001b:  call       void sf.Program::'<Main>g__msd|0_0'(string,
                                                           string,
                                                           string,
                                                           string,
                                                           string)
  IL_0020:  nop
  IL_0021:  call       string [mscorlib]System.Console::ReadLine()
  IL_0026:  pop
  IL_0027:  ret
} // end of method Program::Main

从以上。 我发现最大stakc其不被推送弹出指令来确定价值。

我不知道什么叫真正的堆栈数的值。 所以,我引用ildasm反汇编代码,以确定真正的最大堆栈值。



文章来源: How does the .NET IL .maxstack directive work?