zoukankan      html  css  js  c++  java
  • 翻译:关于Evaluation Stack

      由于没想到合适的 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 结束
  • 相关阅读:
    [NOI2003][bzoj1507] 文本编辑器 editor [splay]
    GDKOI 游记
    [填坑完毕] 寒假作业计划
    省选算法学习-数据结构-splay
    NOIP2017游记
    真·总结
    赛前
    十一黄(xun)金(lian)周感想
    9.17 模拟赛
    9.14 模拟赛
  • 原文地址:https://www.cnblogs.com/cc299/p/14539782.html
Copyright © 2011-2022 走看看