x86架构与x64架构在函数于栈中调用过程的不同之处
时间:2022-07-23
本文章向大家介绍x86架构与x64架构在函数于栈中调用过程的不同之处,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本篇原创作者:Rj45
x86架构与x64架构
1、x86架构 x86架构是intel开发的一种32位的指令集。8个32位通用寄存器 eax,ebx,ecx,edx,ebp,esp,esi,edi
。
2、x64架构 x64架构是64位的,有16个通用寄存器 rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15
。
程序
1、代码
2、编译链接
32位:
sudo gcc stack.c -o stack -m32
64位:
sudo gcc stack.c -o stack1
x86架构下函数于栈中调用过程
0804840b <Add>:
804840b: 55 push ebp //将ebp压入栈
804840c: 89 e5 mov ebp,esp //将esp压入栈
804840e: 83 ec 08 sub esp,0x8 //抬高栈帧
8048411: 8b 55 08 mov edx,DWORD PTR [ebp+0x8] //将[ebp+0x8]压入edx
8048414: 8b 45 0c mov eax,DWORD PTR [ebp+0xc] //将[ebp+0xc]压入eax
8048417: 01 d0 add eax,edx //将eax与edx中的内容相加赋给eax
8048419: 83 ec 08 sub esp,0x8 //抬高栈帧
804841c: 50 push eax //将eax压入栈
804841d: 68 e0 84 04 08 push 0x80484e0 //压入x+y=
8048422: e8 b9 fe ff ff call 80482e0 <printf@plt> //调用printf函数
8048427: 83 c4 10 add esp,0x10 //调整栈帧
804842a: 90 nop
804842b: c9 leave
804842c: c3 ret
0804842d <main>:
804842d: 8d 4c 24 04 lea ecx,[esp+0x4]
8048431: 83 e4 f0 and esp,0xfffffff0
8048434: ff 71 fc push DWORD PTR [ecx-0x4]
8048437: 55 push ebp //将ebp压入栈
8048438: 89 e5 mov ebp,esp //将esp压入栈
804843a: 51 push ecx //将ecx压入栈
804843b: 83 ec 04 sub esp,0x4 //抬高栈帧,esp=esp+0x4
804843e: 83 ec 08 sub esp,0x8 //抬高栈帧
8048441: 6a 14 push 0x14 //压入参数20
8048443: 6a 0a push 0xa //压入参数10
8048445: e8 c1 ff ff ff call 804840b <Add> //调用Add函数
804844a: 83 c4 10 add esp,0x10 //调整栈帧
804844d: b8 00 00 00 00 mov eax,0x0 //清空eax
8048452: 8b 4d fc mov ecx,DWORD PTR [ebp-0x4] //将[ebp-0x4]内的数据赋给ecx
8048455: c9 leave //mov esp,ebp;pop ebp
8048456: 8d 61 fc lea esp,[ecx-0x4] //取[ecx-0x4]中的数据赋给esp
8048459: c3 ret //pop eip
804845a: 66 90 xchg ax,ax
804845c: 66 90 xchg ax,ax
804845e: 66 90 xchg ax,ax
x64架构下函数于栈中调用过程
0000000000400526 <Add>:
400526: 55 push rbp //将rbp压入栈中
400527: 48 89 e5 mov rbp,rsp //将rsp压入栈中
40052a: 48 83 ec 10 sub rsp,0x10 //抬高栈帧
40052e: 89 7d fc mov DWORD PTR [rbp-0x4],edi //将edi的值赋给[rbp-0x4]
400531: 89 75 f8 mov DWORD PTR [rbp-0x8],esi //将rsi的值赋给[rbp-0x10]
400534: 8b 55 fc mov edx,DWORD PTR [rbp-0x4] //将[rbp-0x4]的值赋给edx
400537: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8] //将[rbp-0x8]的值赋给eax
40053a: 01 d0 add eax,edx //eax=eax+edx
40053c: 89 c6 mov esi,eax //将eax的值赋给esi
40053e: bf 04 06 40 00 mov edi,0x400604 //将0x400604对应的数据赋给edi
400543: b8 00 00 00 00 mov eax,0x0 //清空eax
400548: e8 b3 fe ff ff call 400400 <printf@plt> //调用printf函数
40054d: 90 nop
40054e: c9 leave
40054f: c3 ret
0000000000400550 <main>:
400550: 55 push rbp //将rbp压入栈中
400551: 48 89 e5 mov rbp,rsp //将rsp压入栈中
400554: 48 83 ec 10 sub rsp,0x10 //抬高栈帧
400558: 89 7d fc mov DWORD PTR [rbp-0x4],edi //将edi的值赋给[rbp-0x4]
40055b: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi //将rsi的值赋给[rbp-0x10]
40055f: be 14 00 00 00 mov esi,0x14 //将参数20赋给esi
400564: bf 0a 00 00 00 mov edi,0xa //将参数10赋给edi
400569: e8 b8 ff ff ff call 400526 <Add> //调用Add函数
40056e: b8 00 00 00 00 mov eax,0x0 //清空eax
400573: c9 leave //mov esp,ebp;pop ebp
400574: c3 ret //pop eip
400575: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
40057c: 00 00 00
40057f: 90 nop
总结
x86架构与x64架构在函数于栈中调用过程的不同之处在于:x86架构下,函数的参数是直接存放到栈帧中的;而x64架构下,函数的参数是通过寄存器传参进入栈帧的。(当寄存器不够用,才会将参数直接存入栈帧)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python suds访问webservice服务实现
- 使用Python-OpenCV消除图像中孤立的小区域操作
- PHP实现数组和对象的相互转换操作示例
- PHP单元测试框架PHPUnit用法详解
- PHP5中使用mysqli的prepare操作数据库的介绍
- php中的explode()函数实例介绍
- ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
- PHP的mysqli_rollback()函数讲解
- PHP中十六进制颜色与RGB颜色值互转的方法
- PHP后台备份MySQL数据库的源码实例
- PHP的PDO连接讲解
- PHP生成指定范围内的N个不重复的随机数
- 实例讲解通过PHP创建数据库
- PHP的mysqli_select_db()函数讲解
- PHP的PDO事务与自动提交