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.hqwc.cn/news/144587.html

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

相关文章

mac 升级node到指定版本

node版本14.15.1升级到最新稳定版18.18.2 mac系统 先查看一下自己的node版本 node -v开始升级 第一步 清除node的缓存 sudo npm cache clean -f第二步 安装n模块【管理模块 n是管理 nodejs版本】 sudo npm install -g n第三步升级node sudo n stable // 把当前系统的 Node…

【C语言练习题】添加逗号

✨博客主页&#xff1a;小钱编程成长记 &#x1f388;博客专栏&#xff1a;C语言练习题 添加逗号 1. 题目2.讲解3.代码总结 1. 题目 牛客网在线OJ 2.讲解 因为数字位数可能不全是3的倍数&#xff0c;比如&#xff1a;23&#xff0c;445&#xff0c;555。所以我们从后向前进行&…

uni-app:对数组对象进行以具体某一项的分类处理

一、原始数据 这里定义为五个数组&#xff0c;种类product有aaa,bbb两种 原始数据在data中进行定义 res: {"success": true,"devices": [{no: 0,product: aaa,alias: "设备1",assign: [["a1", "a2", "a3"],[&q…

24-数据结构-内部排序-基数排序

基数排序 基数排序&#xff0c;给关键字分成d位&#xff08;组&#xff09;&#xff0c;&#xff0c;对每一位的情况&#xff0c;可能会出现的值位r&#xff08;基数&#xff09;个&#xff0c;然后分成r个队列&#xff0c;对每个对林进行分配耗时O(n)&#xff0c;最后按照改位…

行业追踪,2023-10-20

自动复盘 2023-10-20 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

基于Java的旅游网站系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

在没有康托尔对角化方法的情况下证明实数的不可数性

乔治康托尔 |图片来源&#xff1a; 维基百科 一、说明 对于那些对数学感兴趣的人来说&#xff0c;无穷大实际上可以有不同的大小&#xff0c;这可能是一个众所周知的事实。事实上&#xff0c;最著名的例子是所有实数的集合比所有自然数的集合“大”。你可能知道&#xff0c;这实…

自然语言处理---注意力机制

注意力概念 观察事物时&#xff0c;之所以能够快速判断一种事物(当然允许判断是错误的)&#xff0c;是因为大脑能够很快把注意力放在事物最具有辨识度的部分从而作出判断&#xff0c;而并非是从头到尾的观察一遍事物后&#xff0c;才能有判断结果。正是基于这样的理论&#xf…

第十六届中国智慧城市大会 | 国产化三维重建技术服务智慧城市建设

2023年10月13日&#xff0c;由武汉大势智慧科技有限公司、飞燕航空遥感技术有限公司主办的第十六届智慧城市大会-实景三维技术创新与应用论坛在广州成功举办。 来自实景三维、自然资源、数字孪生、AI大数据、航空遥感等多个领域的专家&#xff0c;深度分享各自的智慧城市建设经…

AirPods Pro的降噪功能让你体验更好,那么如何打开这个功能

本文介绍了如何在AirPods Pro上使用降噪功能&#xff0c;如何关闭它&#xff0c;以及该功能的工作原理。 AirPods Pro和AirPods Max支持降噪。你的设备必须运行iOS 13.2或iPadOS 13.2或更高版本才能使用降噪。 如何在AirPods Pro上打开降噪功能 AirPods Pro凭借其噪音控制功…

SOLIDWORKS 2024新功能 3D CAD三维机械设计10大新功能

SOLIDWORKS 2024新增功能 - 3D CAD三维机械设计 10大新增功能 1. 先前版本的兼容性 •利用您订阅的 SOLIDWORKS&#xff0c;可将您的 SOLIDWORKS 设计作品保存为旧版本&#xff0c;与使用旧版本 SOLIDWORKS 的供应商无缝协作。 •可将零件、装配体和工程图保存为最新版本…