일부 테스트 코드를 디버그 모드로 컴파일하고 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 스택 카운터입니까, 아니면 이것 뒤에 의미가 있습니까?
내 세계에서 IL_0014의 첫 번째 ldloc.0은 절대로 제거되지 않지만 어쩌면 get_Item의 callvirt가 작동하지 않는 것일 수도 있습니다. 내가 IL_0014에 도달했을 때 스택의 내 종이에 목록에 대한 참조가 있어야하고 그 후에 IL_0015에서 0이 평가 스택에 푸시 될 때 프로그램이 .maxstack을 위반합니다.
저는 초보자입니다. 그래서 옳지 않은 것이 있어야합니다. 어쩌면 제 카운팅이 옳고, 맥스 스택에 대한 제 이해가 잘못되었거나, 아마도 다른 방향 일 수도 있습니다. 누군가 .maxstack에 대한 나의 이해가 잘못되었다고 말해도 되겠습니까? .maxstack은 런타임에 스택의 최대 요소를 보여줍니다. 아니면 내 계산이 잘못 됐습니까? Add는 목록 인스턴스에 대한 참조를 제거합니까?
편집 : 다음은 내가 계산 한 것입니다. 카운트는 일리노이 코드가 실행 된 후입니다.
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)
제가 잘못 알고 있다는 것을 알고 있기 때문에 카운트하지 않았습니다. 당신이 잘못된 곳
감사
어떻게 세고 있는지 명확하지 않아 잘못했을 수도있는 것을보기가 어렵습니다. 'callvirt'가 스택에서 타겟과 인수를 띄우는 것을 고려 했습니까? ECMA-335의 III.4.2 절 참조. –
죄송합니다. 나는 내 대답을 내가 얼마나 세 었는지 업데이트했다. 나는 ECMA를 읽지 않았다. 나는 그것을 사실적으로 찾고 있었다. 나는 일리노이에서 녹슬 었어. 감사! 어쩌면 그 callvirt도 참조를 팝하지 않을까요? – mslot
'0e'은 arraylist 참조 번호와 숫자를 띄운 다음'Int32'를 푸시합니다. 잘못 되었다면 arraylist 참조가 갑자기 나타났습니다. –