函数在栈中的调用过程
时间:2022-07-23
本文章向大家介绍函数在栈中的调用过程,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本篇原创作者:Rj45
背景
1、代码
2、编译
sudo gcc stack.c -o stack -m32
反调试
gdb
gdb stack
objudmp
objudmp -d stack -M intel
栈特点
栈是一种线性存储的数据结构,向下增长。其存在栈底和栈顶,栈对其中的数据元素有进栈和出栈的操作,遵循‘First In last Out’即FILO原则。
分析
1、main函数
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 //抬高栈帧
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
2、Add函数
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
3、图示
这是一张函数在栈中的调用过程图
- 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 数组属性和方法
- 一文搞懂Flink rocksdb中的数据恢复
- Linux expect用法介绍
- GitHub通过access token来clone代码
- 在.NET Core中使用MongoDB明细教程(1):驱动基础及文档插入
- 探索闭包
- openresty实现接口签名安全认证
- JavaScript空值合并运算符
- ROS1&2极简版安装配置案例(Noetic&Foxy@Ubuntu20.04)
- Java调用微信扫一扫
- 响应式布局新方案:融合响应式设计,开源 React 组件
- C++核心准则E.26:如果无法抛出异常,尽快进行失败处理
- 学习|C#的EventHandler的委托使用
- 性能分析(5)- 软中断导致 CPU 使用率过高的案例
- C++核心准则E.27:如果无法抛出异常,系统化运用错误处理代码
- C++核心准则E.28:避免基于全局状态的错误处理(例如errno)