微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 计算IL代码中的maxstack值

我有以下程序来添加值.
当我在main方法调用Add方法调用并查看ILDASM.EXE时,Maxstack大小为2.并且在取消注释后,maxstack大小变为4.

为什么在Main方法的情况下所有变量都不会进入堆栈,因为堆栈大小仅为2,而在Add方法调用的情况下,每个变量都进入堆栈?
这是主要方法计算内部逐个发生的情况,因此一次只需要两个变量.

请清除我的困惑.

static void Main(string[] args)
{
    int x = 2;
    int y = 3;
    int a = 4;
    int b = 5;
    int c = 6;

    Console.WriteLine(x + y + a + b + c);
    Console.WriteLine(Add(10,20,30,40));
    Console.ReadLine();
}

static int Add(int x,int y,int z,int a)
{
    return x + y + z + a;
}

解决方法

每个变量初始化:
int x = 2;

将要求值在堆栈上:(堆栈大小:到目前为止需要1)

.locals init ([0] int32 x,[1] int32 y,[2] int32 a,[3] int32 b,[4] int32 c)
IL_0000:  ldc.i4.2  // push 2 to the stack
IL_0001:  stloc.0   // load local variable 0 from stack ( x = 2 )

这些操作按顺序发生,因此在下列期间,所需的最大堆栈大小仍为1:

int y = 3;
int a = 4;
int b = 5;
int c = 6;

当涉及到这个:

Console.WriteLine(x + y + a + b + c);

添加任何两个变量,需要堆栈大小为2:

IL_000b:  ldloc.0 // copy to stack x,max stack size required is still 1.
IL_000c:  ldloc.1 // copy to stack y,max stack size required is 2 Now.
IL_000d:  add     // execute add,will cause the sum x + y to be on stack
IL_000e:  ldloc.2 // copy to stack a
IL_000f:  add     // execute add... (adds a to the result of x + y)
....

取消注释Add方法时的差异IL如下所示.

调用方法时,需要将实例引用推送到堆栈(意味着,如果Add方法是非静态的,则应将指向其声明类型的实例指针推入堆栈)

然后,每个需要传递给方法的参数也应该被压入堆栈.

因此,在您的情况下,它是Add方法的参数数量,它定义了最大堆栈大小.向此Add方法添加一个参数,您将看到最大堆栈大小将增加到5:

// method is static so no need to push an instance pointer to the stack
IL_001a:  ldc.i4.s   10 // push to stack
IL_001c:  ldc.i4.s   20 // push to stack
IL_001e:  ldc.i4.s   30 // push to stack
IL_0020:  ldc.i4.s   40 // push to stack
IL_0022:  call       int32 Program::Add(int32,int32,int32)
IL_0027:  call       void [mscorlib]System.Console::WriteLine(int32)

原文地址:https://www.jb51.cc/csharp/91227.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐