我想知道如何.maxstack真正发挥作用。 我知道这并不与你在声明类型的实际大小,但它们的数量做。 我的问题是:
- 这是否适用于只是为了功能,还是对所有我们所要求的功能呢?
- 即使它只是对功能进行.maxstack正在申报,你怎么知道什么是maxstack如果你有分支? 你去看看所有的“路径”,返回的最大可能值?
- 如果我将其设置为16,会发生什么,实际上有17个变量?
- 有没有太大的罚款,如果我将它设置为256?
我想知道如何.maxstack真正发挥作用。 我知道这并不与你在声明类型的实际大小,但它们的数量做。 我的问题是:
.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
要回答你的问题:
- 这是否适用于只是为了功能,还是对所有我们所要求的功能呢?
只是为了功能
- 即使它只是对功能进行.maxstack正在申报,你怎么知道什么是maxstack如果你有分支? 你去看看所有的“路径”,返回的最大可能值?
你去看看所有的路径,并返回可能的最大值
- 如果我将其设置为16,会发生什么,实际上有17个变量?
这是无关的变量的数目,看到拉塞·五卡尔森的回答
- 有没有太大的罚款,如果我将它设置为256?
似乎不是个好主意,但我不知道。
你真的要计算.maxstack
自己呢? System.Reflection.Emit
IIRC计算它。
它无关的声明的变量数量 ,而是一切都与你需要多少价值,以便计算一些表达推栈在任何给定的时间。
例如,在下面的表达式,我会假设2个值需要被压入堆栈:
x = y + z;
这是无关的事实,即至少有3个变量存在,X,y和z,以及可能还有其他。
不幸的是,我不知道答案你的其他问题,我猜想的实验是要找到一些答案的一种方式。
您可以参考以下内容,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
反汇编代码,以确定真正的最大堆栈值。