函数堆栈
来源:互联网 发布:2017淘宝网下载 编辑:程序博客网 时间:2024/05/29 19:20
#include <windows.h>int func002(char *str, int len){ strcpy(str, "hello"); return len; }int func001(int x, char y, char *z){ char buff[10]; int aa; func002(z, aa); return 0x100;}void main_call(){ int a; char b; char c[100]; func001(a, b, c); func002(c, a);}void main(){ main_call();}
对应的反汇编代码:cl /Fac1.asm cat.c
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 TITLEE:\code\ctoasm\cat.c.686P.XMMinclude listing.inc.modelflatINCLUDELIB LIBCMTINCLUDELIB OLDNAMES_DATASEGMENT$SG76990 DB'hello', 00H_DATAENDSPUBLIC_func002EXTRN_strcpy:PROC; Function compile flags: /Odtp_TEXTSEGMENT_str$ = 8; size = 4_len$ = 12; size = 4_func002 PROC; File e:\code\ctoasm\cat.c; Line 5pushebpmovebp, esp; Line 6pushOFFSET $SG76990moveax, DWORD PTR _str$[ebp]pusheaxcall_strcpyaddesp, 8; Line 8moveax, DWORD PTR _len$[ebp] //eax才是函数返回值,len实际未赋值; Line 9popebpret0_func002 ENDP_TEXTENDSPUBLIC_func001; Function compile flags: /Odtp_TEXTSEGMENT_aa$ = -4; size = 4_x$ = 8; size = 4 //0的前面压栈了pc和ebp。_y$ = 12; size = 1_z$ = 16; size = 4_func001 PROC; Line 12pushebpmovebp, espsubesp, 20; 00000014H; Line 16moveax, DWORD PTR _aa$[ebp]pusheaxmovecx, DWORD PTR _z$[ebp]pushecxcall_func002addesp, 8; Line 18moveax, 256; 00000100H //返回值; Line 19movesp, ebppopebpret0_func001 ENDP_TEXTENDSPUBLIC__$ArrayPad$PUBLIC_main_callEXTRN___security_cookie:DWORDEXTRN@__security_check_cookie@4:PROC; Function compile flags: /Odtp_TEXTSEGMENT_c$ = -120; size = 100 //字节对齐108,并填充12字节,所以分配的局部变量空间是120B__$ArrayPad$ = -12; size = 4_b$ = -5; size = 1_a$ = -4; size = 4_main_call PROC; Line 22pushebp // 每一级的ebp指向上一级的esp起始地址。movebp, espsubesp, 120; 00000078Hmoveax, DWORD PTR ___security_cookiexoreax, ebpmovDWORD PTR __$ArrayPad$[ebp], eax //&*%*&%; Line 27leaeax, DWORD PTR _c$[ebp] //为什么不都用eax?pusheaxmovzxecx, BYTE PTR _b$[ebp] //赋值并清零。pushecxmovedx, DWORD PTR _a$[ebp]pushedxcall_func001addesp, 12; 0000000cH // 调用者将压栈参数弹出堆栈。; Line 29moveax, DWORD PTR _a$[ebp]pusheaxleaecx, DWORD PTR _c$[ebp]pushecxcall_func002addesp, 8; Line 30movecx, DWORD PTR __$ArrayPad$[ebp]xorecx, ebpcall@__security_check_cookie@4 // 大概是堆栈检查的调试功能。movesp, ebp // 前面将esp保存到ebp中,这里恢复esp的取值,相当于丢弃了局部变量空间。popebpret0_main_call ENDP_TEXTENDSPUBLIC_main; Function compile flags: /Odtp_TEXTSEGMENT_mainPROC; Line 33pushebpmovebp, esp; Line 34call_main_call; Line 35xoreax, eax //eax存放函数返回值popebpret0_mainENDP_TEXTENDSEND
汇编代码的核心是ESP、EBP的设计。
ESP是函数堆栈指针,每次PUSH减4,每次pop加4.
EBP是每个函数的基址指针,表示该函数的“起始堆栈”,可用户函数返回后恢复堆栈,类似盗梦空间的kick处理。
- 函数堆栈
- 函数堆栈
- 函数堆栈
- 函数堆栈变化原理
- 函数调用堆栈分析
- 函数调用堆栈分析
- 堆栈与函数调用
- 函数调用 堆栈
- 堆栈与函数调用
- 堆栈与函数调用
- 堆栈与函数调用
- backtrace函数与堆栈
- 堆栈与函数调用
- 函数调用 堆栈
- 函数调用堆栈分析
- 堆栈输出函数
- 函数调用 堆栈
- 函数调用堆栈分析
- ref参数和out参数
- 项目计划
- IOS 文件操作
- POJ.Fermat vs. Pythagoras
- hdu 1671 Phone List(二叉树)
- 函数堆栈
- Leetcode: N-Queens II
- MarkdownPad使用心得小窍门--> 开源code编辑工具
- VS2010 C++编译报错LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- oracle 最基本命令
- ubuntu12.04安装java6,验证可用
- SDL 和SDL_TTF 联合实现 Video Player 加OSD
- java中print,printf,println区别
- 快速生成树协议(Rapid STP,RSTP)