【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

相关文章

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑