EBP寄存器存着啥东西,跟函数返回有啥联系啊
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EBP寄存器存着啥东西,跟函数返回有啥联系啊相关的知识,希望对你有一定的参考价值。
进入函数时要保存ebp的值, 然后用来存放进入函数时esp的值,方便进行堆栈内的寻址, 函数返回要恢复ebp的值, 除此以外,ebp和函数返回没什么关系====================================================================
在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等。在win32的环境下EBP寄存器用与存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的。
应用以前说过的一段话:
原程序的OEP,通常是一开始以 Push EBP 和MOV Ebp,Esp这两句开始的,不用我多说大家也知道这两句的意思是以EBP代替ESP,作为访问堆栈的指针。
为什么要这样呢?为什么几乎每个程序都是的开头能?因为如果我们写过C等函数的时候就应该清楚,程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的:
1.让EBP保存ESP的值;
2.在结束的时候调用
mov esp,ebp
pop ebp
retn
或者是
leave
retn
两个形式是一个意思。
这样做的好处是不用考虑ESP等于多少,PUSH了多少次,要POP多少次了,因为我们知道EBP里面放的是开始时候的ESP值。 参考技术A 进入函数时要保存ebp的值, 然后用来存放进入函数时esp的值,方便进行堆栈内的寻址, 函数返回要恢复ebp的值, 除此以外,ebp和函数返回没什么关系
为什么要这样呢?为什么几乎每个程序都是的开头能?因为如果我们写过C等函数的时候就应该清楚,程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的:
1.让EBP保存ESP的值;
2.在结束的时候调用
mov esp,ebp
pop ebp
retn
两个形式是一个意思。
这样做的好处是不用考虑ESP等于多少,PUSH了多少次,要POP多少次了,因为我们知道EBP里面放的是开始时候的ESP值。 参考技术B PASCAL是一种函数调用的方式,确定参数压栈的顺序,还有由谁来恢复堆栈,具体的可以看下下面的链接。还有这里:
C语言中函数调用过程(如何管理栈空间)
ps:先做草稿,以后有时间再整理并贴图,:)
主要是利用栈底寄存器(ebp)、栈顶寄存器(esp)跟eax寄存器(存储返回值)来实现。
假设P调用Q:
P()
{
Q(1,2);
}
1.调用前准备,将Q的参数放到栈中(非push)
mov $1, (%esp)
mov $2, 4(%esp)
2.调用call 0x12345678 (Q的地址)
首先将函数的返回地址(call语句后的那条指令的地址)进栈,
然后跳到0x12345678执行Q的代码。
3.将旧的ebp进栈(用于退出Q时还原)
push %ebp
4.设置新的栈底
mov %esp, %ebp
5.为Q分配栈空间(栈是向下生长的)
sub $24, %esp (16 * k + 8,用于对齐)
6.执行Q的相关代码。局部变量/参数是根据esp、ebp跟偏移量来进行存取的。
7.函数离开前将返回值赋值给%eax。
8.调用leave,相当于:
mov %ebp, %esp (还原栈顶)
pop %ebp (还原栈底)
9.处理返回值并接着P接着的代码继续执行。
以上是关于EBP寄存器存着啥东西,跟函数返回有啥联系啊的主要内容,如果未能解决你的问题,请参考以下文章