调用堆栈和评估堆栈是如何相关的?

Ban*_*San 3 .net c# vb.net callstack cil

第二次尝试表达这一点:

我正在采取一些步骤来掌握一些MSIL.

我一直听到"评估堆栈"被称为堆栈,操作在加载,使用等时被推送和加载.

因此,给出以下代码:

public class Program
{
    public static void Main()
    {
        var message = GetMessage();

        Console.WriteLine(message);
    }

    public static string GetMessage()
    {
        return "Hello World!";
    }
}
Run Code Online (Sandbox Code Playgroud)

MSIL看起来如此:

.class public auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor () cil managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    }

    .method public hidebysig static string GetMessage () cil managed 
    {
        .locals init (
            [0] string V_0
        )

        IL_0000: nop
        IL_0001: ldstr "Hello World!"
        IL_0006: stloc.0
        IL_0007: br.s IL_0009

        IL_0009: ldloc.0
        IL_000a: ret
    }

    .method public hidebysig static void Main () cil managed 
    {
        .entrypoint
        .locals init (
            [0] string V_0
        )

        IL_0000: nop
        IL_0001: call string Program::GetMessage()
        IL_0006: stloc.0
        IL_0007: ldloc.0
        IL_0008: call void [mscorlib]System.Console::WriteLine(string)
        IL_000d: nop
        IL_000e: ret
    }
}
Run Code Online (Sandbox Code Playgroud)

认为开头的行IL_xxxx是评估堆栈(如果我错了请纠正我).所以该行call string Program::GetMessage()是调用另一个方法的行.

所以,我想我问的问题是:

  1. 每行都以IL_0000"新"评估堆栈开头吗?
  2. 调用堆栈是否在运行时看到此IL的连接\连接\过滤?

usr*_*usr 5

我认为以IL_xxxx开头的行是评估堆栈

每行以IL_0000开头是一个"新"评估堆栈吗?

不.每种方法都有一个评估堆栈.把它想象成一个Stack<object>.IL指令通过推送和弹出项目对该堆栈进行操作.MSDN文档精确地调用每个IL操作码的堆栈行为.

调用堆栈与评估堆栈无关.调用堆栈是Call Stack Visual Studio窗口向您显示的内容.

调用堆栈是否在运行时看到此IL的连接\连接\过滤?

没有.没有关系.

我觉得你对评估堆栈的思考太复杂了.这是一个非常简单的概念.只要你有一些复杂的想法,你就没有把握它.不过,我不确定误解到底在哪里.

请注意,评估堆栈是用于定义IL程序含义的逻辑概念.与调用堆栈(禁止内联)确实存在相比,它在运行时不再存在.