.NET IL .maxstack 指令如何工作?

发布于 2024-07-29 21:56:11 字数 310 浏览 5 评论 0 原文

我想知道 .maxstack 是如何工作的。 我知道这与您声明的类型的实际大小无关,而是与它们的数量有关。 我的问题是:

  1. 这是否仅适用于 函数,或所有函数 我们所呼吁的?
  2. 即使只是为了功能 正在声明 .maxstack, 你怎么知道 maxstack 是多少 你有分支吗? 你去看看 所有“路径”并返回 可能的最大值?
  3. 如果我将其设置为 16 并且会发生什么 实际上有17个变量?
  4. 如果我这样做的话,惩罚是否太大了? 设置为256?

I'd like to know how does .maxstack really work. I know it doesn't have to do with the actual size of the types you are declaring but with the number of them. My questions are:

  1. does this apply just for the
    function, or to all the functions
    that we are calling for?
  2. even if it's just for the function
    were .maxstack is being declared,
    how do you know what maxstack is if
    you have branching? You go and see
    all the "paths" and return the
    maximum value possible?
  3. What happens if I set it to 16 and
    actually there are 17 variables?
  4. Is there a too big of a penalty if I
    set it to 256?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

原野 2024-08-05 21:56:17

您可以参考以下内容和 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 反汇编代码来确定真正的最大堆栈值。

You can refer to the following and the ECMA STANDARD to get a better understanding:

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

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

When I run ildasm.exe I got this:

{
  .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

from the above. I found the max stakc value which isn't determined by the push & pop instructions.

I didn't know what the real stack number values are. So, I reference the ildasm disassembly code to determine the real max stack value.

别把无礼当个性 2024-08-05 21:56:16

它与声明的变量的数量无关,而是与在任何给定时间需要将多少值压入堆栈以计算某个表达式有关。

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

x = y + z;

这与至少存在 3 个变量(x、y 和 z,可能还有其他变量)的事实无关。

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

It has nothing to do with the number of variables declared, but instead everything to do with how many values you need to push on a stack at any given time in order to compute some expression.

For instance, in the following expression, I would assume 2 values needs to be pushed onto the stack:

x = y + z;

This is unrelated to the fact that there are at least 3 variables present, x, y, and z, and possibly others as well.

Unfortunately I don't know the answer to your other questions, and I would guess experimentation would be one way to find some answers.

葬心 2024-08-05 21:56:15

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

(Pseudo 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. 这仅适用于该函数,还是适用于我们调用的所有函数?

只是为了功能

  • 即使只是声明 .maxstack 的函数,如果有分支,你怎么知道 maxstack 是什么? 你去查看所有“路径”并返回可能的最大值?
  • 你去查看所有路径并返回可能的最大值

  • 如果我将其设置为 16,但实际上有 17 个变量,会发生什么?
  • 与变量的数量无关,参见Lasse V. Karlsen的回答

  • 如果我将其设置为 256,惩罚会不会太大?
  • 似乎不是一个好主意,但我不知道。

    您真的需要自己计算 .maxstack 吗? System.Reflection.Emit 为您计算 IIRC。

    .maxstack is part of the IL verification. Basically .maxstack tells the JIT the max stack size it needs to reserve for the method. For example, x = y + (a - b) translates to

    (Pseudo 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
    

    As you can see, there are at most 3 items on the stack at each time.
    If you'd set .maxstack to 2 (or less) for this method, the code wouldn't run.

    Also, you cannot have something like this as it would require an infinite stack size:

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

    To answer your questions:

    1. does this apply just for the function, or to all the functions that we are calling for?

    Just for the function

    1. even if it's just for the function were .maxstack is being declared, how do you know what maxstack is if you have branching? You go and see all the "paths" and return the maximum value possible?

    You go and see all the paths and return the maximum value possible

    1. What happens if I set it to 16 and actually there are 17 variables?

    It's unrelated to the number of variables, see Lasse V. Karlsen's answer

    1. Is there a too big of a penalty if I set it to 256?

    Doesn't seem like a good idea, but I don't know.

    Do you really have to calculate the .maxstack yourself? System.Reflection.Emit calculates it for you IIRC.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文