函数调用时的堆栈变化(实例)

2023-11-10

函数调用时的堆栈变化

关于函数调用是的堆栈变化,在网上找到的资料大都是一些配图文字等,理解起来尚有些困难,不过建议大家还是先了解一下基本的原理,下面我主要通过一个调用函数的实例来讲解一下函数调用时的堆栈变化(Ps:图片有点糊,大家最好自己跟着做一遍叭)

测试函数如下:

#include <iostream>

int add_1912080143(int x, int y)
{
    int z = 0;
    z = x + y;
    return z;
}
void main()
{
    int n = 0;
    n = add_1912080143(1, 3);
    printf("%d\n", n);
}
1. 在VC++6.0中新建项目将函数代码复制上去

在这里插入图片描述

2.在函数调用处下断点,按F5进行调试

在这里插入图片描述

3.点击图示按钮查看程序的汇编代码

在这里插入图片描述

4.对汇编代码进行简单的分析
  1. int n = 0 的汇编代码为 mov dword ptr [ebp-4],0 这里n为局部变量所以在栈中存储,ebp为基址支持寄存器存储的是栈帧的起始地址在这里插入图片描述
  2. F10单步执行程序push 3, push 1这里是将调用函数的两个参数从右到左依次入栈
    在这里插入图片描述
  3. 继续F10单步执行,这里先不进入函数分析函数执行完之后的代码 add esp,8 这里是因为前面向栈中push了两个参数每个int占4字节,所以将esp(栈顶指针)加8个字节恢复到push参数之前的状态(注意:向栈中加数据是从高地址向低地址移动),mov dword ptr [ebp-4],eax将函数的返回值赋值给n,eax寄存器用来保存函数的返回值,[ebp-4]是n的值(这里的ebp是不变的因为在调用函数的时候会保存现场,具体过程可以看下面进入函数后的代码分析)
    在这里插入图片描述
5.对进入函数后的汇编代码进行分析
  1. 在call指令处按F11进入函数,这里注意一下执行完函数后的下一条指令的地址00401098
    在这里插入图片描述
  2. 按下F11后程序并没有立即跳转到代码区,我们查看查看一下栈中的内容,可以看到栈顶的数据为00401098(这里的存储方式采用小端存储注意顺序),而这正是执行完函数后的下一条指定的地址,由此我们判断这一步执行的操作时将程序执行完后的下一条指令地址入栈
    在这里插入图片描述
  3. F10继续执行来到代码区,首先将四个寄存器的值入栈保护现场,当函数执行完的时候再出栈,这也就是为什么4.3步中ebp的值不变的原因,然后mov ebp,esp sub esp,44h是为add函数开辟一段大小为44h的栈帧,ebp是栈帧的基址,esp为栈顶指针,这里add函数与main函数的栈帧是连续的,esp是main函数的栈顶指针所以可以将esp的值直接赋给ebp作为add函数栈帧的基址
    在这里插入图片描述
  4. 接下来的四条语句为初始化栈帧的操作,ebp-44h为esp的值,ecx通常用来计数,下面还有一条rep循环指令,这四条语句最终的效果就是将add栈帧的值全都初始化为CCh
    在这里插入图片描述
  5. 接下来分析程序执行时的三段语句
    第一段语句是局部变量的声明,ebp为add函数栈帧的基址,所以直接ebp-4的地址分给变量z
    第二段语句中[ebp+8]和[ebp+0ch]存储的都是最开始入栈的函数参数的值,这一步的结果存在eax中,然后将eax的值返回给[ebp-4]也就是变量z(ebp+和参数相关,ebp-和局部变量相关)
    第三段语句因为函数的返回值通常保存在eax寄存器中,而这个函数返回的是变量z,所以将变量z的值赋给eax
    在这里插入图片描述
  6. 最后一部分为恢复现场,与函数最开始保护现场的部分一一对应,ebp的值赋给esp
    在这里插入图片描述

附录

lea指令的用法
rep和stos指令的用法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数调用时的堆栈变化(实例) 的相关文章

随机推荐

  • Spring Cloud Alibaba,中国 Javaer 的福音,为微服务续上 18 年

    h2 Spring Cloud Alibaba 中国 Javaer 的福音 为微服务续上 18 年 nbsp h2 p 热 p p a href https my oschina net u 3820517 h4cd a nbsp 发布于
  • Vue指令 关于---v-html_指令 和 v-test_指令 详解

    要学会大大方方的表达爱意 爱不是冷冰冰 爱是炙热的 永远都是 笨蛋才会说反话 笨蛋才会把喜欢的人越推越远 一 在讲解 v test 指令 和v html 指令 前我么先回顾一些基本指令 v bind 单项绑定解析表达式 可简写为 xxx v
  • day6-列表的遍历,增删查改,比较运算,列表推导式,列表的相关函数

    列表基础学习 一 遍历列表 1 遍历列表 二 列表的增删查改操作 1 增 1 列表 append 元素 2 列表 insert 下标 元素 2 删 删除元素 1 del 列表 下标 2 列表 remove 元素 3 列表 pop 下标 列表
  • Win7、Win10系统封装后GHO文件太大?是因为虚拟内存没关、休眠文件没删!

    很多镜像文件封装好都是3 5g的 而最近我自己封装系统 封装完是8g 百度才知道是C盘有休眠文件大概5 4g 下图是我正在用的电脑删除休眠文件后的大小对比 删除休眠文件方法 1 在开始栏的 附件 里面找到 命令提示符 右击 以管理员身份运行
  • 文举论金:3.17黄金原油全面走势分析策略指导。

    市场没有绝对 涨跌没有定势 所以 对市场行情的涨跌平衡判断就是你的制胜法宝 欲望 有句意大利谚语 让金钱成为我们忠心耿耿的仆人 否则 它就会成为一个专横跋扈的主人 空头 多头都能赚钱 唯有贪心不能赚 是你掌控欲望还是欲望掌控你 古人云 不积
  • 使用eclipse创建一个图书管理系统(1)-----搭建架构

    目录 思维导图 图书管理系统的创建 第一步 搭建框架 使用者 第二步 搭建框架 被使用者 第三步 操作方法 第四步 main函数 思维导图 前言 昨天学了一下使用Java语言来写一个图书管理系统 于是今天写一篇博客作为一个小笔记巩固一下自己
  • git 打包两个版本差异

    git archive o update zip 当前版本号 git diff name only 上一版本号
  • QMainWindow和QWidget

    一 QMainWindow QmainWindow主窗口为用户提供一个应用程序框架 它有自己的布局 可以在布局中添加控件 在主窗口中可以添加控件 比如将工具栏 菜单栏 状态栏等添加到布局管理器中 窗口类型介绍 QMainWindow QWi
  • 人工智能技术发展历史

    人工智能 Artificial Intelligence 简称 AI 的历史可以追溯到上世纪50年代 以下是其中的关键点 1956年 达特茅斯会议 1956年 美国达特茅斯学院举办了一次会议 邀请了一些研究者共同探讨人工智能的概念 目标和方
  • 【NLP入门教程】三、词性标注

    词性标注 Part of Speech Tagging POS Tagging 是自然语言处理中的另一个基本任务 它涉及将文本中的每个词元 Token 标注为其对应的词性 如名词 动词 形容词等 词性标注有助于我们理解文本的语法结构 进而支
  • win10 家庭版系统安装docker desktop遇到那些坑

    最近开发中需要用到docker来打包镜像 由于我的电脑系统是win10 家庭版 而docker desktop针对win10系统只支持64 位的 Windows 10 专业版 企业版和教育版 我又不想重装系统 因为要重装一堆工具 太麻烦了
  • FILCO Majestouch Convertible 2 键盘连接电脑说明

    键盘连接新电脑频次比较低 每次都忘记了怎么操作 要去翻说明书 上网找方法 在此记录下圣手2代键盘连接新电脑或者切换电脑的连接方式
  • Python数据可视化matplotlib.pyplot的使用

    1 生成数据 安装matplotlib windows cmd中 pip install matplotlib 在Python环境下 使用import matplotlib检测是否安装成功 不报错就是安装成功 重启写py的工具就可以进行使用
  • 2020东京奥运会奖牌排行--数据可视化

    爬取数据1 1 数据来源 https 2020 cctv com medal list index shtml 数据为下面图片的表格数据 2 具体代码 2 1需要提前下载好的pip install 库名 from selenium impo
  • Windows 下 VSCode 使用 SSH 连接报 Bad owner or permissions on C:\\Users\\Administrator/.ssh/config 错误问题解决

    Windows 下 VSCode 使用 SSH 连接报 Bad owner or permissions on C Users Administrator ssh config 错误问题解决 vscode ssh 链接报错情况 解决方法 v
  • JAVA环境变量配置方法(Windows)

    编写一个JAVA程序后 如果想让自己编写的代码可以正常运行 我们便需要对它进行编译和运行 而Java环境变量的配置就显得尤为重要 本篇文章 我们来谈一谈关于Java环境变量配置的一些方法 目录 方法一 方法二 方法三 方法一 1 右击 我的
  • ARP协议

    什么是ARP 地址解析协议 即ARP Address Resolution Protocol 是根据IP地址获取物理地址的一个TCP IP协议 主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机 并接收返回消息 以此确定
  • vue 字符串、数组之间的相互转换

    1 字符串转数组 str split 以分号拆分字符串 2 数组转字符串 arr join 把数组项拼接成字符串 并以分号隔开 默认情况下是以逗号隔开
  • Linux系统迁移(同一台电脑),重建UEFI启动文件

    电脑型号 hp 暗影精灵5 Air 显卡 RTX 2060 CPU i7 9750H 硬盘 500G固态 1T固态 启动方式 UEFI 操作系统 Ubuntu16 04 之前安装Ubuntu的时候给Ubuntu系统分配的空间太小了 安装新硬
  • 函数调用时的堆栈变化(实例)

    函数调用时的堆栈变化 关于函数调用是的堆栈变化 在网上找到的资料大都是一些配图文字等 理解起来尚有些困难 不过建议大家还是先了解一下基本的原理 下面我主要通过一个调用函数的实例来讲解一下函数调用时的堆栈变化 Ps 图片有点糊 大家最好自己跟