Я скомпилировал некоторый тестовый код в режиме отладки и отразил полученную сборку с ILSpy. Это IL Я получаю:Объяснить директиву maxstack для меня
.class private auto ansi beforefieldinit ArrayListBoxAndUnBox.Program
extends [mscorlib]System.Object
{
// Nested Types
.class nested public auto ansi beforefieldinit Point
extends [mscorlib]System.Object
{
// Fields
.field public int32 x
.field public int32 y
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Method begins at RVA 0x209f
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Point::.ctor
} // end of class Point
// Methods
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 59 (0x3b)
.maxstack 2
.entrypoint
.locals init (
[0] class [mscorlib]System.Collections.ArrayList list,
[1] int32 i,
[2] class ArrayListBoxAndUnBox.Program/Point p
)
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: box [mscorlib]System.Int32
IL_000e: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
IL_0013: pop
IL_0014: ldloc.0
IL_0015: ldc.i4.0
IL_0016: callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
IL_001b: unbox.any [mscorlib]System.Int32
IL_0020: stloc.1
IL_0021: ldloc.0
IL_0022: newobj instance void ArrayListBoxAndUnBox.Program/Point::.ctor()
IL_0027: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
IL_002c: pop
IL_002d: ldloc.0
IL_002e: ldc.i4.1
IL_002f: callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
IL_0034: castclass ArrayListBoxAndUnBox.Program/Point
IL_0039: stloc.2
IL_003a: ret
} // end of method Program::Main
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Method begins at RVA 0x2097
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
} // end of class ArrayListBoxAndUnBox.Program
Я вижу .maxstack установлен в два, но когда я иду через код вручную иногда я получаю 3 элемента в стек оценки. Зачем? Я плохой счетчик IL-стека, или есть смысл позади этого?
В моем мире первый ldloc.0 на IL_0014 никогда не удаляется, но, возможно, это просто я не понимаю, как работает callvirt для get_Item. Когда я добираюсь до IL_0014, у меня есть ссылки на список на моей бумаге стека, и после этого в IL_0015 программа нарушает .maxstack, когда 0 помещается в стек evalution.
Я новичок, поэтому должно быть что-то, что не так. Возможно, мой подсчет прав, и мое понимание .maxstack неверно, или, может быть, это наоборот. Может кто-нибудь, пожалуйста, скажите мне, не ошибается ли мое понимание .maxstack, что .maxstack показывает максимальные элементы в стеке во время выполнения. Или если мой счет ошибочен? Добавляет ли удаление ссылку на экземпляр списка?
EDIT: Вот как я рассчитываю. Счет после запуска кода IL:
IL_0000: 0 on stack
IL_0001: 1 on stack (the reference to array list)
IL_0006: 0 on stack
IL_0007: 1 on stack (the reference to arraylist)
IL_0008: 2 on stack (reference to arraylist and int 1)
IL_0009: 2 on stack (refernce to arraylist and reference to object that wrap 1)
IL_000e: 2 on stack (reference to arraylist and index to the added boxed int object)
IL_0013: 1 on stack (reference to arraylist)
IL_0014: 2 on stack (reference to arraylist and reference to arraylist)
IL_0015: 3 on stack (reference to arraylist and reference to arraylist and int 0)
Я не считал остальное, потому что знаю, что у меня что-то не так.
Thanks
Непонятно, как вы рассчитываете, что очень сложно понять, что вы, возможно, сделали неправильно. Вы учли, что 'callvirt' выталкивает цель и аргументы из стека? См. Раздел III.4.2 ECMA-335. –
Извините. Я обновил свой ответ так, как я считаю. Я не читал ECMA. Я все это искал. Я немного ржавый в своем IL. Благодаря! Может быть, я не понимаю, что callvirt также выдает ссылку? – mslot
'0e' выдает как ссылку на arraylist, так и номер, а затем нажимает' Int32' - вот где вы поступили не так, вы не заметили, что ссылка на arraylist была выскочена. –