从汇编代码探究函数栈帧的创建和销毁的底层原理(一)

简介: 从汇编代码探究函数栈帧的创建和销毁的底层原理

一、先导知识

C/C++中内存分为3个区域:栈区、堆区、静态区

不同性质的变量存放在不同的内存区域中,下图是各种变量所在内存中的区域
本文所讲的函数栈帧的创建和销毁过程就是在栈区进行的


栈区存放变量的特点:先存高地址,再存低地址。


销毁变量的时候是先销毁低地址里面的变量,再销毁高地址里面的变量,如图


例如:变量1先创建,再创建变量2......创建变量8;但是销毁的时候,就是先销毁变量8......最后销毁变量1

本文中将用到的两个寄存器:ebp、esp,这两个指针中存放的是地址,用来维护函数栈帧

ebp是栈底指针、esp是栈顶指针正在调用哪个函数,ebp、esp就维护哪个函数的函数栈帧

二、函数调用堆栈

在vs2013中来测试并观察main函数栈帧的创建过程

F10-->调试-->窗口-->调用堆栈  一直按F10直到程序结束,就会出现下面的场景

可以看到main函数是由626行的那个函数 __tmainCRTStartup函数调用的
而  __tmainCRTStartup 函数又是由466行的   mainCRTStartup 函数调用的,调用的顺序正是由栈顶往栈底

三、函数栈帧的创建

1.创建函数栈帧

有(二)中可知,VS2013中,main函数也是被其他函数调用的,每一次函数调用都要在栈区上分配空间,接下来就通过观察汇编代码来看观看函数栈帧的创建,假设mian函数中还有一个Add函数,来计算两个数的相加的和。按下F10后不要乱动,右击鼠标,转到反汇编(C语言对应的汇编代码)

这就是这段代码对应的汇编代码

由于main函数是由 __tmainCRTStartup函数调用的,所以在调用main函数前,main函数的函数栈帧已经创建好了

push:给栈顶放一个元素

push          ebp 将ebp里面的值放在栈顶,同时因为esp指向的是栈顶,所以esp指针也‘上移’

如图

mov:将前面的值放到后面值的地方

mov        ebp,esp,将ebp指针移动到esp指针的位置

sub:前面的值减去后面的值

sub         esp,0E4h,指针esp减去0E4h(一个8进制的数字),并移动指针esp

由于ebp是栈底指针,esp是栈顶指针,正在调用哪个函数,ebp和esp就维护哪个函数的函数栈帧

后面调用Add函数的时候,ebp、esp就去维护Add函数的函数栈帧。

所以栈区中mian函数的调用空间(预开辟)就开辟好了连续push三次,将这三个元素依次放到栈顶,压栈三次

同时esp也移动到栈顶

lea:load effecitive address   加载有效地址

lea             edi,[ebp-0E4h]  把  ebp-0E4h 的地址放到edi里面去,而ebp-0E4h应该就是main函数的栈顶地址


mov           ecx,39h 把39h的值放入eax中去


mov           eax,0CCCCCCCCh 把0CCCCCCCCh的值放入eax中


rep stos     dword ptr es:[edi] 把从 edi(edp-0E4h)开始向下ecx(39h)次 dword 的数据全部都改成 eax(0CCCCCCCC) (dword(双字节))图例


简单的来讲就要将从 edp-0E4h 到 ebp 中间所有的内容初始化为0ECCCCCCCC

假设初始化完了(没有画全),意思就是中间全部初始化为0CCCCCCCC此时main函数才开始执行代码


相关文章
|
4月前
|
存储 编译器 程序员
C语言之反汇编查看函数栈帧的创建与销毁(一)
C语言之反汇编查看函数栈帧的创建与销毁(一)
C语言之反汇编查看函数栈帧的创建与销毁(一)
|
28天前
|
C语言
51单片机汇编语言流水灯代码
51单片机汇编语言流水灯代码
|
3月前
|
Python
python 代码脚本汇编
python 代码脚本汇编
32 0
|
4月前
|
Java C++
如何在JAVA代码中嵌入汇编
如何在JAVA代码中嵌入汇编
62 1
|
4月前
|
Windows
86/88汇编代码的运行调试
86/88汇编代码的运行调试
35 0
|
4月前
|
存储 编译器 程序员
C语言之反汇编查看函数栈帧的创建与销毁(二)
C语言之反汇编查看函数栈帧的创建与销毁(二)
|
4月前
|
Java Windows
查看java文件汇编代码与字节码
查看java文件汇编代码与字节码
79 0
|
9月前
|
编译器 C语言
函数栈帧的创建和销毁(以C语言代码为例,汇编代码的角度分析)(下)
函数栈帧的创建和销毁(以C语言代码为例,汇编代码的角度分析)
|
4月前
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
82 1
|
4月前
|
存储 机器学习/深度学习 移动开发
汇编语言指令系列
汇编语言指令系列
185 0