C++之寄存器(EIP、ESP、EBP)

三种寄存器:EIP、ESP、EBP

1、EIP寄存器里存储的是CPU下次要执行的指令的地址。也就是调用完函数返回后,让CPU知道函数返回后继续继续执行哪一条指令。

2、EBP寄存器里存储的是是栈的栈底指针,通常叫栈基址,这个是一开始进行函数调用之前,由ESP传递给EBP的。(在函数调用前:ESP存储的是栈顶地址,也是栈底地址。)

3、ESP寄存器里存储的是在调用函数之后,栈的栈顶。并且始终指向栈顶。

#include <stdio.h>  
int fun2(int x, int y, int z)  
{  
    int i = x + y;  
    int j = y + z;  
    int k = i + j;  
    return k;  
}  
int fun1(int a, int b)  
{  
    int c = a + b;  
    int d = 0;  
    d = fun2(a, b, c);  
    return d;  
}  
int main()  
{  
    int num1 = 10;  
    int num2 = 20;  
    fun1(num1, num2);  
    return 0;  
}  

main调用fun1函数前:

1)main函数的栈空间num1变量已经赋值为10, num2变量赋值为20;
2)ESP 是栈指针寄存器这个寄存器中存储着栈顶的地址,EBP中存储着栈底的地址;

main调用fun1函数时:

1)实参num2的数值被复制到了形参b所在的内存中;
2)实参num1的数值被复制到了形参a所在的内存中;
3)ESP的数值也随着不断减小以指向栈顶;

4)保存函数fun1返回后main下一条要执行指令的地址EIP。将EIP保存到当前ESP所指向的栈空间中;
5)保存当前函数的栈底EBP到ESP所指向内存中去, ESP 和EBP都指向相同地址。
6)为fun1中有两个局部变量c和d分配空间;

fun1函数,调用fun2函数:

1)实参c的数值复制到了形参z所在的内存中;
2)实参b的数值复制到了形参y所在的内存中;
3)实参a的数值复制到了形参x所在的内存中;

4)保存fun2返回后,func1执行下一条函数的地址EIP;
5)保存栈底EPB地址,同时上移EBP到ESP;

6)为内部变量i,j,k分配空间;

函数返回:

fun2函数回退,fun2的栈空间已经不再有效,局部变量会被释放,如何把这个返回结果80传递到fun1中?数据存于寄存器中,寄存器有32(32位CPU)位和64位(64位CPU),只能存储基本数据类型和指针(结构体或类)。

函数退出时栈的变化,恢复到fun1栈空间

1)先移除fun2的内部变量,即ESP和EBP指向相同地址,ESP中存放的是fun1的EBP地址;

2)恢复原来EBP的数值;

3)找到fun1中返回后,下一条执行指令地址;

4) 彻底恢复到fun1的栈空间,fun2的栈空间不再有效。 函数退出后原来使用的数值计算机并没有做多余的回收工作(杜绝野指针,即返回返函数局部变量的指针)。

5) 返回值保存到了寄存器eax中的,d的数值是从寄存器eax中取得。

恢复到main栈空间

发表回复