转自网络:
在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比 如: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值。
2个重要的指针寄存器(ESP和EBP)
这两个指针寄存器都和“栈”这个神秘的东东有关,那么什么是栈呢?这俩指针寄存器又有何作用呢?
从计算机科学的角度看,栈是一种数据结构,是一种先进后出的数据表。栈的最常见操作有两种:Push(入栈)和Pop(出栈)。
我们可以把栈想象成一摞扑克牌:
PUSH:为栈增加一个元素的操作是push,相当于在这摞扑克牌最上面再放一张
POP:从栈中取出一个元素的操作叫做POP,相当于从这摞扑克牌取出最上面的一
张。
TOP:标识栈顶位置,并且是动态变化的。每做一次PUSH 操作,它都会自增1;
相反,每做一次POP 操作,它会自减1。栈顶元素相当于扑克牌最上面一张,只有
这张牌的花色是当前可以看到的。
BASE:标识栈底位置,它记录着扑克牌最下面一张的位置。BASE 用于防止栈空后
继续弹栈(牌发完时就不能再去揭牌了)。很明显,一般情况下,BASE 是不会变动
的。
用王爽《汇编语言》中的图说明一下push和pop操作
代码如下:
mov ax,0123H
push ax
mov bx,2266H
push bx
mov cx,1122H
pop ax
pop bx
pop cx
mov是传送数据的指令,mov ax,0123H表明把0123H这个值给ax
H代表0123是十六进制数
mov是传送数据的指令,mov ax,0123H表明把0123H这个值给ax
H代表0123是十六进制数
图中左边的10000H等数值表明内存地址
箭头指向栈顶位置
那么针对此例栈底就是1000FH
栈顶由于入栈和出栈操作在不断变化。
那么在这里栈底1000FH就是BP 栈顶(不断变化的箭头)就是SP
(BP和SP分别是16位下的寄存器,与ebp,esp类似)
内存的栈区实际上指的就是系统栈。系统栈由系统自动维护,它用于实现高级语言中函
数的调用。对于类似C 语言这样的高级语言,我们无需担心他们是如何操作的。一般说来,只有在使用汇编语言的时候,才需要和它直接打交道。
那么ESP和EBP指的分别是什么呢?
(1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
(2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。