#include<stdio.h>intAdd(int a,int b){int x =0;
x = a + b;return x;}intmain(){int a =10;int b =20;int ret =Add(a, b);printf("%d\n", ret);return0;}
2.寄存器了解
EBP:扩展基址指针寄存器(extended base pointer) ,用于存放函数栈底指针。 ESP:扩展栈指针寄存器(Extended Stack Pointer),用于存放函数栈顶指针。
而这两个指针就是维护这次函数调用创建的栈帧。
二、函数调用分步式讲解
首先大家要明白的是,在进入到main内部时,我们通过调试窗口的函数调用堆栈观察到 main 函数被调用起来了(上图),那么main函数被谁调用了呢,在代码调试完之后可以在反汇编代码626行看到 __tmainCRTStartup()调用了main函数,同样,该函数又被 在466行的mainCRTStartup()所调用(下图)。那么在为main函数开辟栈帧空间前还要为这两个函数的调用开辟栈帧空间,这两个函数不是重点,我们从main函数的调用开始讲解。
int x =0;00DD13DE mov dword ptr [ebp-8],0//在ebp向上移动八个字节的这块空间就为 x 的空间,并将内容初始化为0
x = a + b;00DD13E5 mov eax,dword ptr [ebp+8]//[ebp+8]--> ebp指针向下移动八个字节找到10存到eax中00DD13E8 add eax,dword ptr [ebp+0Ch]//[ebp+0Ch]--> ebp指针向下移动十二个字节找到20与eax中的10相加,//再将和放入到eax中00DD13EB mov dword ptr [ebp-8],eax //将eax中的值存放到[ebp-8],也就是 x 的空间}
5.Add函数返回
return x;00DD13EE mov eax,dword ptr [ebp-8]//返回值,在函数执行完后将在[ebp-8]处的运算结果传给eax寄存器//通过eax寄存器将结果返回00DD13F1 pop edi
00DD13F2 pop esi
00DD13F3 pop ebx
00DD13F4 mov esp,ebp
00DD13F6 pop ebp //这五条语句是将ADD函数的栈帧空间进行释放,并且ebp,esp返回到main函数的栈帧空间00DD13F7 ret //此时Add函数已经执行完,通过这个ret就会找到mian函数空间的 call指令的下一条地址,继续执行下一条代码
每次 pop 完成之后相应的esp,ebp指针都会调整其指向的位置,在(pop ebp)完成之后ebp指向之前在mian函数空间的位置,而esp会指向call指令下一条指令的地址。