【C++】汇编分析

2024-08-30 09:52
文章标签 分析 c++ 汇编

本文主要是介绍【C++】汇编分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传参

有的是用寄存器传参,有的用push传参
我在MSVC编译测出来的是PUSH传参(debug模式),具体过程如下

long func(long a, long b, long c, long d,long e, long f, long g, long h) {long sum;sum = (a + b + c + d + e + f + g + h);return sum;
}int main() {long sum;sum = func(1, 2, 3, 4, 5, 6, 7, 8);std::cout << sum << std::endl;return 0;
}

调用方:

汇编
在这里插入图片描述

push 是将操作数压到栈顶,然后移动栈顶(esp)
push前:
在这里插入图片描述
push一次后:
在这里插入图片描述
call前:
在这里插入图片描述

进入函数func

汇编
在这里插入图片描述
分析:

  1. 前3条是经典的移动堆栈
    移动后:
    在这里插入图片描述
    注意这个ebp = 00ff68c, 理论上它应该是等于call前的esp即00ff694,为何相差8.
    首先push ebp让esp向下移动4,剩下的4是函数返回地址,即call指令的下一条指令地址
    具体栈信息如图:
    在这里插入图片描述
    可以看到栈从下往上,先压入了参数,后压入了call前的ebp。

返回值

在这里插入图片描述

可见是通过eax寄存器返回的。

总结

可以回答以下几个问题:

  1. 如何传参,通过push指令将参数压入栈,然后call
  2. 参数放在哪:因为调用是先push再call, 进入函数后参数在栈下面,也就是不在[ebp, esp)这个范围内,通过ebp+x来取得参数。
  3. 局部变量在哪:进入函数后的3条指令开辟了新的栈空间即[ebp, esp), 局部变量在栈空间内,通过ebp-x来取值。
  4. 函数执行完恢复调用方的堆栈信息:进入函数后先将调用方的ebp压入栈,然后移动堆栈,调用方的ebp就存在当前栈底,即ebp指向的就是,退出函数时有个mov esp, ebp;pop ebp 动作就是将栈底的值给ebp寄存器。就恢复了调用方的堆栈
  5. 返回值,返回值简单时通过寄存器返回。
  6. 为什么参数的入栈信息总是从右到左:栈是向上增长的,先入栈的参数处于高位地址,压栈完后从低地址往高地址看,参数顺序就是从左向右了。
  7. ret指令: 跳转到当前栈顶的地址,然后esp-4
  8. call指令:将下一条指令地址压入栈,然后esp+4
  9. 调用函数栈信息如下:
//func的栈
-esp
...
-ebp   ----- 调用方的ebp
-ebp-4  返回地址
- ebp-8 参数1
- ...
- 参数 n

这篇关于【C++】汇编分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120483

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C