• 6.栈、栈帧


    栈(Stack)的用途广泛,通常用于存储局部变量、传递函数参数、保存函数返回地址等。调试程序时需要不断查看栈内存,所以掌握栈很重要。

    栈是FILO(First In Last Out,后进先出)这个都知道。但是在看汇编的时候一定要注意一些对应的相关细节。比如函数调用的时候,反汇编看到的参数进栈顺序是倒着的等。

    栈的特征

    内存结构如下:

     

    一个进程中,栈顶指针(ESP)初始状态指向栈底端。执行PUSH命令将数据压入栈时,栈顶指针就会上移到站顶端。执行POP命令从栈中弹出数据时,若栈为空,则指针重新移动到栈底端。栈时一种由高地址向低地址扩展的数据结构,是由下往上扩展的(逆向扩展)。

    所以 向栈压入数据时,栈顶指针减小,向低地址移动;从栈中弹出数据时,栈顶指针增加,向高地址移动。初始的时候栈顶指针指向占地。

     

    栈帧(Stack Frame) 栈帧在程序中用于声明局部变量、调用函数。

    栈帧就是利用EBP(栈帧指针,请注意不是ESP)寄存器访问栈内局部变量、参数、函数返回地址等的手段。ESP寄存器承担着栈顶指针的作用,而EBP寄存器则负责形式栈帧指针的职能。程序运行中,ESP寄存器的值随时变化,访问栈中函数的局部变量、参数时,若依ESP值为基准编写程序会十分困难,并且也很难使CPU引用到准确的地址。所以,调用某函数时,先要把用作基准点(函数起始地址)的ESP值保存到EBP,并维持在函数内部。这样,无论ESP的值如何变化,以EBP的值为基准(base)能够安全访问到相关函数的局部变量、参数、返回地址,这就是EBP寄存器作为栈帧指针的作用。

     

    提示:某些优化选项可能会优化掉栈帧。


    源代码vs2015 C++

    #include "stdafx.h"
    
    #include <iostream>
    
    #include <windows.h>
    
    using namespace std;
    
    
    
    long add(long a, long b) {
    
    long x = a, y = b;
    
    return (x + y);
    
    }
    
    
    
    int main(){
    
    long lNumbera = 1;
    
    long lNumberb = 2;
    
    printf("%d
    " ,add(lNumbera , lNumberb));
    
        return 0;
    
    }

    编译运行(Debug)之后OD加载上,找到add函数,看下栈帧操作。

     

  • 相关阅读:
    使用SocketAsyncEventArgs犯的低级错误
    使用Beetle简单构建高性能Socket tcp应用
    构造BufferWriter和BufferReader实现高效的对象序列化和反序列化
    c#编写高性能Tcp Socket应用注意事项
    文件上传下载流程设计
    识别支点
    interface 与 delegate
    小知识:ADO.NET中的连接池
    解决问题
    IBM把Rational这个软件彻底给毁了
  • 原文地址:https://www.cnblogs.com/csnd/p/12061882.html
Copyright © 2020-2023  润新知