栈帧
了解函数的调用过程以及函数栈帧
我们知道每一次函数调用都是一个过程,这个过程我们通常称之为:数的调过程。
这个过程要为函数开辟栈空间,用于本次函数的调用中临时变量的保存、现场保护。这块栈空间我们称之为函数栈帧。
而堆栈的维护需要了解ebp和esp这两个寄存器。在函数的调用过程中这两个寄存器存放了维护这个栈的栈底和栈顶指针。
下面以一个例子进行说明:求两数的和。
#include <stdio.h> #include <windows.h> int fun(int a,int b) { int c=0; c=a+b; return c; } int main() { int a=10; int b=20; printf("%d ",fun(a,b)); system("pause"); return 0; }
寄存器
EBP:基址寄存器
ESP:栈顶寄存器
EIP:指令寄存器、程序寄存器
call作用:
(1).默认将现在所指指令的下一条指令地址压入栈中;
(2).跳转到目标函数的地址;
ret:弹回栈顶地址,放在EIP寄存器中,就会返回到之前的代码。
思考:函数调用在调用子程序时要存放正在执行指令的下一条指令地址,以便返回到主函数,可以通过改变返回值地址来改变返回值,也可将返回值的地址调用到其他子函数中,也可改变返回值。
(1).可通过跳转到子函数的地址加上偏移量来改变某些参数的值;比如上例所述,将 fun的(012413D0h)加4就是形参b的地址,因而可以改变b的值;
(2).返回地址下面再套一个子程序,那么,子程序执行完后返回到该地址上,可改变其原本要返回的内容。