X32位汇编和X64位区别无参函数分析(一)

前言

一、X32汇编函数无参无返回分析

二、X64汇编函数无参无返回分析

总结


前言

提示:以下是个人学习总结:如有错误请大神指出来,只供学习参考,本内容使用使用VS2017开发工具:语言是C++,需要一些常见的汇编指令,寄存器的概念,不会的可以看下其他的博主的,我用的这里方便学习全程debug,函数用的默认C++cdecl调用约定模式(可以网上查下调用约定,右边入参到左边,称为外平栈)。


好久没更新博客了,准备把汇编自我总结复习的顺带把过程记录下来,接下来开始吧,准备简单的无参函数。

一、X32汇编函数无参无返回分析

1.代码图片(示例):

不知道为什么不能赋值图这里直接赋值代码了。
#include <iostream>void shenjianxz() {int a;int c;int d = 3;int d2 = 4;a = d - d2;
}int main()
{shenjianxz();}

0099179E call        00991131 这个就是上面那个简单shenjianxz()函数调用,

CPU主要执行的是根据EIP执行跳转的,

call指令会 push 009917A3 压栈 :因为我们调用完函数返回的时候会取这个地址,跳转到下一行执行的代码,  EIP寄存器=00991131

现在我们跳去看看按F11

这里 jmp    中间跳转程序空间保存的函数地址    00EA1750,咱们先不管,这不是重点

简单解下:jmp 只改变eip地址,cpu会自动运行到执行的地址去,在点下F11进入 调用函数代码区了。

重点关注下:ESP寄存器到哪了,EBP寄存器值等于多少。

我讲解下上面代码含义:

shenjianxz
009918F0  push        ebp  

保留ebp 寄存器
009918F1  mov         ebp,esp  
为了后面恢复esp栈顶位置把他赋值给ebp进行操作
009918F3  sub         esp,0F0h  

因为前面已经保存了esp的赋值,就不担心这里esp就开始扩展0F0h 位置esp位置肯定就变了
009918F9  push        ebx  
009918FA  push        esi  
009918FB  push        edi  
保留 ebx,esi,edi 寄存器位置
009918FC  lea         edi,[ebp-0F0h]  

这里ebp的作用就体现了,最前面我们不是把esp赋值给了ebp吗,
这里就代表把sub         esp,0F0h  地址赋值给edl

00991902  mov         ecx,3Ch    3c次数
00991907  mov         eax,0CCCCCCCCh  
0099190C  rep stos    dword ptr es:[edi]  
重复3c次把occccccch=int 3先不用管,就理解是ccccccc赋值给edi 每次成功赋值就 edi+4
0099190E  mov         dword ptr [ebp-20h],3  
00991915  mov         dword ptr [ebp-2Ch],4  
0099191C  mov         eax,dword ptr [ebp-20h]  
0099191F  sub         eax,dword ptr [ebp-2Ch]  

ebp的位置是push ebp的位置,之后不是 ebp=esb 下一句不是 sub         esp,0F0h  扩展了0f0的大小空间么
那么ebp-20,-2c都是在扩展的位置区间,可见X32是ebp-N代表取局部变量

00991922  mov         dword ptr [ebp-8],eax  
最终把结果放到ebp-8内存中
00991925  pop         edi  
00991926  pop         esi  
00991927  pop         ebx  
因为esp一直在栈顶所以还原3个寄存器 esp-Ch位置
00991928  mov         esp,ebp  
esp已经距离很远了,因为扩展了0F0h大小字节,所以用ebp恢复esp位置esp在 push ebp位置了
0099192A  pop         ebp  
恢复ebp栈底
0099192B  ret  
之前我们用call 调用的函数,这里面push的是 call的下一条代码地址=pop eip 让cpu跳转到eip位置,下面是对应的自己画的图:

2.小结:
    1:X32是先保留push ebp寄存器,在扩展堆栈大小
    2:mov         ebp,esp 保留栈顶位置,方便后面恢复
    3:[ebp-20],[ebp-2c]都是在扩展的位置区间,可见X32是ebp-N代表取局部变量,参数获取(这里演示无参数)

二、X64汇编函数无参无返回分析

1.代码图片(示例)

同样的代码看不同:

前面讲过,这里也是jmp方式跳转到函数代码快,继续F11跟进去,因为中间重启过地址发生变化,直接看下面的函数内容就行

00007FF7CA1717C0  push        rbp  
00007FF7CA1717C2  push        rdi  
00007FF7CA1717C3  sub         rsp,168h  
00007FF7CA1717CA  lea         rbp,[rsp+20h]  
00007FF7CA1717CF  mov         rdi,rsp  
00007FF7CA1717D2  mov         ecx,5Ah  
00007FF7CA1717D7  mov         eax,0CCCCCCCCh  
00007FF7CA1717DC  rep stos    dword ptr [rdi]  
这里是重复ecx的次数填充栈顶开始往回每次 rdi+4
00007FF7CA1717DE  lea         rcx,[__D730393F_c@cpp (07FF7CA181027h)] 
00007FF7CA1717E5  call        __CheckForDebuggerJustMyCode (07FF7CA171087h)
这2行 因为是debug模式是检测堆栈的直接跳过看下面的  
00007FF7CA1717EA  mov         dword ptr [rbp+44h],3  
00007FF7CA1717F1  mov         dword ptr [rbp+64h],4  
RBP+N 代表局部变量,在X32中是EBP-N代表局部变量,那么这里就是把立即数赋值给局部变量
我的理解因为之前 扩展168h,rsp,168h 
这里局部变量不能>rbp+148h大小范围,因为rsp+20了之前,大于了下一条就到了push rdi的位置了

00007FF7CA1717F8  mov         eax,dword ptr [rbp+64h]  
00007FF7CA1717FB  mov         ecx,dword ptr [rbp+44h]  
看这里rbp+64 ,+44都是在扩展的局部变量赋值,在范围内
00007FF7CA1717FE  sub         ecx,eax  
00007FF7CA171800  mov         eax,ecx  
00007FF7CA171802  mov         dword ptr [rbp+4],eax  
最后把值赋值给局部变量rbp+4
00007FF7CA171805  lea         rsp,[rbp+0000000000000148h]  
之前rsp-168h,然后rbp+20 这里在加个148h 不就回去了最早的push RDI位置
00007FF7CA17180C  pop         rdi  
00007FF7CA17180D  pop         rbp  
这里就是恢复 RDI RBP里的值
00007FF7CA17180E  ret  这里pop eip 让cpu跳转到调用程序下一条指令执行

 


三、X32位汇编和X64位区别无参函数调用

总结

提示:可以看下对比堆栈图变化和我说的文字区别

X32:
    1:X32是先保留push ebp寄存器,在扩展堆栈大小
    2:mov         ebp,esp 保留栈顶位置,方便后面恢复
    3:[ebp-20],[ebp-2c]都是在扩展的位置区间,可见X32是ebp-N代表取局部变量,参数获取(这里演示无参数)

X64:

   1:X64是先扩展栈顶大小,在进行保留寄存器
    2:EBP+N是获取局部变量
    3:EBP+20=ESP+20,后用EBP进行局部变量赋值,参数获取(这里演示无参数)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/168655.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL1——喵喵期末不挂科

宝宝&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重要…

阶段六-Day04-MyBatis2

一、别名 Alias 1. 为什么使用别名 一般映射文件中会包含大量<select>标签, 每个<select>中都需要配置resultType"com.bjsxt.pojo.People"&#xff0c;MyBatis提供了别名机制可以对某个类起别名或给某个包下所有类起别名&#xff0c;简化resultType取值…

sklearn-6算法链与管道

思想类似于pipeline&#xff0c;将多个处理步骤连接起来。 看个例子&#xff0c;如果用MinMaxScaler和训练模型&#xff0c;需要反复执行fit和tranform方法&#xff0c;很繁琐&#xff0c;然后还要网格搜索&#xff0c;交叉验证 1 预处理进行参数选择 对于放缩的数据&#x…

性能测试 —— Jmeter 命令行详细

我们在启动Jmeter时 会看见&#xff1a;Don’t use GUI mode for load testing !, only for Test creation and Test debugging.For load testing, use CLI Mode (was NON GUI) 这句话的意思就是说&#xff0c;不要使用gui模式进行负载测试&#xff0c;gui模式仅仅是创建脚本…

Unity 通过jar包形式接入讯飞星火SDK

最近工作上遇到了要接入gpt相关内容的需求&#xff0c;简单实现了一个安卓端接入讯飞星火的UnitySDK。 或者也可以接入WebSocket接口的。本文只讲安卓实现 我使用的Unity版本为2021.3.27f1c2 Android版本为4.2.2 1.下载SDK 登陆讯飞开放平台下载如图所示SDK 2.新建安卓工程…

【广州华锐互动】关于物理力学的3D实验实操平台

在科学的广阔领域中&#xff0c;物理力学是一个至关重要的分支&#xff0c;它探索了物体在力作用下的运动规律。然而&#xff0c;传统的物理实验往往需要复杂的设备和大量的操作&#xff0c;这对于学生来说是一项巨大的挑战。为了解决这个问题&#xff0c;广州华锐互动开发了物…

django 商品及购物车逻辑实现

基于类视图模式实现商品分类菜单接口开发 创建菜单子应用 python manage.py startapp menu测试 apps/menu/views from django.http import HttpResponse from django.views import Viewclass GoodsMainMenu(View):def get(self,request):print("get请求")return …

二叉搜索树进阶--AVL树详细实现过程

目录 AVL树概念AVL树实现AVL树基础结构插入插入&#xff1a;左旋实现插入&#xff1a;右旋实现 AVL树完整实现代码&#xff1a; 之前学习到的二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中…

实现Traefik工具Dashboard远程访问:搭建便捷的远程管理平台

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

HTML笔记-狂神

1. 初识HTML 什么是HTML&#xff1f; Hyper Text Markup Language : 超文本标记语言 超文本包括&#xff1a;文字、图片、音频、视频、动画等 目前使用的是HTML5&#xff0c;使用 W3C标准 W3C标准包括&#xff1a; 结构化标准语言&#xff08;HTML、XML&#xff09; 表现标…

大二第三周总结(算法+生活)

算法&#xff1a; 题目&#xff1a;有效的括号 这个题目也是做过很多回了。主要就是数据结构中”栈“的应用&#xff0c;先进后出。 解题思路&#xff1a; 1.创建 Map 哈希表形成键值对映射 2.进行遍历字符串 在遍历过程中 如果 遍历到的字符c 是左括号&#xff0c;则入栈 pu…

大小端字节序存储

大小端字节序存储&#xff1a;是以字节为单位讨论它在内存中的存储顺序&#xff0c;而不是更小的二进制位 例如&#xff1a; int main() {int a 0x11223344;return 0; }a在内存中的存储16进制为44 33 22 11&#xff0c;两个16进制为一个单位进行存储&#xff0c;而两个十六进…

Leetcode—260.只出现一次的数字III【中等】

2023每日刷题&#xff08;三&#xff09; Leetcode—260.只出现一次的数字III 借助lowbit的解题思想 参考的灵茶山艾府大神的题解 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ int* singleNumber(int* nums, int numsSize, in…

git rebase 和 git merge的区别?

一、是什么 在使用 git 进行版本管理的项目中&#xff0c;当完成一个特性的开发并将其合并到 master 分支时&#xff0c;会有两种方式&#xff1a; git mergegit rebase git rebase 与 git merge都有相同的作用&#xff0c;都是将一个分支的提交合并到另一分支上&#xff0c…

谈谈你对spring boot 3.0的理解

谈谈你对spring boot 3.0的理解 一&#xff0c;Spring Boot 3.0 的兼容性 Spring Boot 3.0 在兼容性方面做出了很大的努力&#xff0c;以支持存量项目和老项目。尽管如此&#xff0c;仍需注意以下几点&#xff1a; Java 版本要求&#xff1a;Spring Boot 3.0 要求使用 Java 1…

Web前端—Flex布局:标准流、浮动、Flex布局、综合案例(短视频首页解决方案)

版本说明 当前版本号[20231024]。 20231024初版 目录 文章目录 版本说明目录Flex布局01-标准流02-浮动基本使用产品区域布局HTML标签CSS样式 清除浮动场景搭建额外标签法单伪元素法双伪元素法overfow法 03-Flex布局Flex组成主轴对齐方式侧轴对齐方式修改主轴方向弹性伸缩比弹…

概率论_概率公式中的分号(;)、逗号(,)、竖线(|) 及其优先级

目录 1.概率公式中的分号(;)、逗号(,)、竖线(|) 2.各种概率相关的基本概念 2.1 联合概率 2.2 条件概率&#xff08;定义&#xff09; 2.3 全概率(乘法公式的加强版) 2.4 贝叶斯公式 贝叶斯定理的公式推导 1.概率公式中的分号(;)、逗号(,)、竖线(|) ; 分号代表前后是两类…

最新Tuxera NTFS2023最新版Mac读写NTFS磁盘工具 更新详情介绍

Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下&#xff0c;MacOSX只能实现对NTFS的读取功能&#xff0c;Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2023完美兼容最新版本的MacOS 11 Big Sur&#xff0c;在M1芯片…

互联网Java工程师面试题·Spring篇·第二弹

目录 3、Beans 3.1、什么是 spring bean&#xff1f; 3.2、spring 提供了哪些配置方式&#xff1f; 3.3、spring 支持集中 bean scope&#xff1f; 3.4、spring bean 容器的生命周期是什么样的&#xff1f; 3.5、什么是 spring 的内部 bean&#xff1f; 3.6、什么是 spri…

【tg】4:NetworkManager :p2p、ice、消息收发

代码分布 NetworkManager 自成体系,看起来也么有啥依赖 class NetworkManager : public sigslot::has_slots<>, public std::enable_shared_from_this<NetworkManager