函数栈帧的创建和销毁(下)

简介: 函数栈帧的创建和销毁(下)

3.1

传参

[ebp-14h]这个地址的值赋给eax

把eax放到栈顶

[ebp-8]这个空间的值赋给ecx

把ecx放到栈顶

3.2

调用add函数:

call         00C210E1

按F11,在进入函数的同时

在栈顶存储00C21450

call指令会在存储call指令下一条指令的地址

目的是在执行完call指令后能返回继续执行下一条指令

4.

进入add函数

a.

为add函数申请内存空间

把main函数的ebp放在栈顶

把esp的值赋给ebp

把esp减去0CCh,使得esp地址向上移

b.

与2.步骤相同

初始化成CCCCCCCCh

c.

此处的[ebp+8]就是ecx,即3.1传参传进来的a,值为10

[ebp+0Ch]就是[ebp+12]就是b

line 4:

把ecx的值赋给eax

line 5:

把eax和[ebp+0Ch]的值相加

line 6:

把eax的值赋给[ebp-8],即z

由此可知,3.1这一步在调用之前就进行传参,将形参b、a通过压栈传到栈顶的目的了

即:

形参不是在add函数内部创建的(并没有另外在add函数内部存储参数,而是直接利用了之前传入的参数)

这很好地解释了:

形参是实参的一份临时拷贝

以及

在传值调用时,改变形参不会影响实参

5.

返回z

line 8:

把[ebp-8]的值赋给eax

注意:eax为寄存器,不会随着函数的结束而销毁

6.1

初步清理:

pop         edi

pop:弹出

意思是:把栈顶的元素弹出,然后存入edi这个寄存器中

这样栈中的元素就少了一个,esp的位置也向下移动一位

pop        esi

pop        ebx

同样是弹出栈顶的元素,分别存入esi、edi这两个寄存器中

6.2回收add函数的内存空间

a.

mov         esp,ebp

把ebp赋给esp

b.

pop         ebp

此时栈顶是main 函数的ebp

这一步是为了找到main函数的栈低

esp同时向下移动一位

这样就回到了原来的main函数

c.

此时的栈顶是call指令下一条指令的地址

ret

ret 指令执行后就回到了call指令的下一条指令处

7.

line 7:

esp+8

目的是将esp向下移动两位

将形参所占空间释放掉

line 8:

把寄存器eax的值(此时eax中寄存着add函数的返回值)赋给[ebp-20h],即c

line 9:

打印c

8.

回收main函数的内存空间

与6.2相同

不再进行解释

结语:

不由得同时感叹编程的复杂和有趣。

相关文章
|
23天前
|
编译器 容器
关于函数栈帧的创建和销毁
关于函数栈帧的创建和销毁
|
2月前
|
容器
函数栈帧的创建和销毁介绍
函数栈帧的创建和销毁介绍
19 0
|
5月前
|
存储 编译器
初识函数栈帧的创建与销毁(笔记)
初识函数栈帧的创建与销毁(笔记)
|
5月前
|
编译器 程序员 C语言
函数栈帧的创建与销毁(超详解)
函数栈帧的创建与销毁(超详解)
64 0
|
6月前
|
存储 缓存 编译器
函数栈帧的创建与销毁
函数栈帧的创建与销毁
24 0
|
6月前
|
存储 C语言 C++
你知道函数栈帧的创建和销毁吗?
你知道函数栈帧的创建和销毁吗?
56 0
|
7月前
|
存储 编译器 C++
深入理解内存 —— 函数栈帧的创建与销毁
深入理解内存 —— 函数栈帧的创建与销毁
70 0
|
9月前
|
存储 编译器
函数栈帧的创建和销毁(上)
函数栈帧的创建和销毁
37 0
|
9月前
|
存储 编译器 C语言
函数栈帧的创建和销毁
函数栈帧的创建和销毁
|
10月前
|
编译器 C语言 容器
函数栈帧的创建和销毁(一)
函数栈帧的创建和销毁
92 1

热门文章

最新文章