1.需要了解的知识
(1)寄存器和内存模型
先来看寄存器。CPU 本身只负责运算,不负责储存数据。数据一般都储存在内存之中,CPU 要用的时候就去内存读写数据。但是,CPU 的运算速度远高于内存的读写速度,为了避免被拖慢,CPU 都自带一级缓存和二级缓存。基本上,CPU 缓存可以看作是读写速度较快的内存。
但是,CPU 缓存还是不够快,另外数据在缓存里面的地址是不固定的,CPU 每次读写都要寻址也会拖慢速度。因此,除了缓存之外,CPU 还自带了寄存器(register),用来储存最常用的数据。也就是说,那些最频繁读写的数据(比如循环变量),都会放在寄存器里面,CPU 优先读写寄存器,再由寄存器跟内存交换数据。

(2)一些寄存器

这里的EBP和ESP两个寄存器存放的是地址,这两个地址是用来维护函数栈帧的
(3)每一个函数调用都要在栈上创建一个空间
(4)函数栈帧的创建和销毁是基于栈所实现的
所谓栈,是一种数据结构,具有先进后出的特点。在函数栈帧创建过程中,内存从高地址开始使用,越后面创建的函数栈帧或压栈数据,所存储的空间地址越低。 
(5)main函数是会被其他函数调用的,在不同编译器中调用main的函数也不同

2.函数栈帧的结构
esp为栈顶指针 ebp为栈底指针 它们共同维护函数栈帧

3.函数栈帧创建与销毁的过程
以如下的加法函数代码块来演示C语言在vs2013上的过程:
#include <stdio.h>
int add(int x, int y)
{
int t;
int t = x + y;
return t;
}
int main()
{
int a = 1;
int b = 2;
int c = 0;
c = add(a, b);
printf("%d\n",c);
return 0;
}

push —— 压栈操作。
push ebp —— 把 ebp 放到现在维护空间的栈顶上面。(这时,esp指针就会向上移动)
mov ebp,esp —— 把 esp 的值给到 ebp 。(就是使 ebp 和 esp 同时指向了现在的栈顶)
sub esp,0E4h —— 使 esp 减去 0E4h(16进制数,使栈顶指针往上移动 0E4h)
这时,esp 和 ebp 维护的空间就变了,变成了 main 函数的函数栈帧(为main函数开辟的空间)
 上面这段代码意思:把从 edi 开始,往下 39h 次的 dword(4)个字节的内容更改为 0CCCCCCCCh(就是把main函数的空间里面都存放 0CCCCCCCCh)
 这段代码就是在给变量a , b, c开辟空间,并初始化赋值。
接下来就是给 Add 函数传参,然后给它创建函数栈帧:  先把 ebp - 14h 这块空间的值赋值到 eax 中(就是b的值20)
在对 eax 压栈,把 eax 放到栈顶上。
同理:把 ebp - 8 这块空间的值赋值到 ecx 中(a的值10)
在对 ecx 压栈,把 ecx 放到栈顶上。
3.总结
对于汇编语言这块,我并不是特别了解,只是初始一些关于计算机组成原理的内容,总的来说关于函数栈帧的创建与销毁这块知识,我还是收获颇丰的!
|