首页 > 其他 > 详细

翻译:关于Evaluation Stack

时间:2021-03-15 22:56:43      阅读:32      评论:0      收藏:0      [点我收藏+]

  由于没想到合适的 Evaluation Stack 对应的中文,索性就不给它中文名了。

Evaluation Stack 是基于 MSIL 应用程序(C#、F#、VB.NET 语言应用)的关键结构,它是应用程序 和 内存之间的桥梁。

它跟普通的栈有一些关键性的区别。

你的应用程序 可以通过 使用 Evaluation Stack ,去访问 函数参数、局部变量、临时对象等。

通常,函数参数和局部变量 是存在内存【栈】上的,但是你的函数 却不能直接访问这些信息。想访问这些数据,必须使用 load 命令,把它们从内存 移动到 Evaluation Stack 的 Slot(槽,4字节或8字节的单元)上;反过来,可以用(store命令)更新Evaluation Stack上的 局部变量或参数。

 

技术分享图片

 

Evaluation Stack 是个栈,因此,也遵循 先进后出(LIFO)的原则。 当函数开始的时候,Evaluation Stack是空的。 随着函数的执行,会向Evaluation Stack里面增删元素。在函数退出前,除有返回值的情况外,Evaluation Stack必须是空。Jmp、Tail命令是这个规则的例外。如果函数退出时Evaluation Stack不为空,CLR会抛出InvalidProgramException 异常。

 

.maxstack 是用来限制 Evaluation Stack 大小的命令,是可选的。如果没有写,默认Evaluation Stack 提供8个Slot。.maxstack 用来确保应用如预期的执行。如果执行时,Evaluation Stack的长度 超过了.maxstack 指定的长度,则可能代表着 程序收到了潜在的逻辑问题 或者安全风险。不管如何,这种情况都值得提醒用户。

 

简言之,Evaluation Stack就是 函数 和 内存间的桥梁。

----------------------------------

以下不是翻译:

以一个简单的函数为例:

public int Add(int fact1, int fact2)
{
    return fact1 + fact2;
}

编译后的IL,可以看出函数的一般“套路”:对参数、返回值、局部变量的读写,就是在操作 Evaluation Stack。

// 方法
    .method public hidebysig 
        instance int32 Add (
            int32 fact1,
            int32 fact2
        ) cil managed 
    {
        // 方法起始 RVA 地址 0x30a4
        // 方法起始地址(相对于文件绝对值:0x12a4)
        // 代码长度 9 (0x9)
        .maxstack 2   //CC note:限定了 这个函数的 evaluation stack 大小是 2。函数执行过程中,,evaluation stack长度不能超过2。否则会有安全告警
        .locals init (
            [0] int32
        )

        // 0x12B0: 00
        IL_0000: nop
        // 0x12B1: 03
        IL_0001: ldarg.1 //CCNote:把第1个参数 加载到 evaluation stack
        // 0x12B2: 04
        IL_0002: ldarg.2 //CCNote:把第2个参数 加载到 evaluation stack
        // 0x12B3: 58
        IL_0003: add     //CCNote:从 evaluation stack 上 pop 出来2个元素,进行加法运算。再把结果 push 到  evaluation stack
        // 0x12B4: 0A
        IL_0004: stloc.0 //CCNote:从 evaluation stack 上 pop 出来1个元素,并把它存到 局部变量列表的 第0号 元素中。
        // 0x12B5: 2B 00
        IL_0005: br.s IL_0007

        // 0x12B7: 06
        IL_0007: ldloc.0 //CCNote:把 局部变量列表的 第0号元素 加载到 evaluation stack
        // 0x12B8: 2A
        IL_0008: ret //CCNote:return 命令, 从 被调函数的 evaluation stack中 Pop出来 顶上元素,然后 push到 调用方的 evaluation stack 中。
    } // 方法 HelloWorld::Add 结束

 

翻译:关于Evaluation Stack

原文:https://www.cnblogs.com/cc299/p/14539782.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!