了解寄存器: EBP寄存器

EBP寄存器

在长期的编程和使用中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等。在win32的环境下EBP寄存器用与存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的。 (ESP用于访问栈顶)

应用以前说过的一段话:

原程序的OEP,通常是一开始以 Push EBP 和MOV Ebp,Esp这两句开始的,不用我多说大家也知道这两句的意思是以EBP代替ESP,作为访问堆栈的指针。

为什么要这样呢?为什么几乎每个程序都是的开头能?因为如果我们写过C等函数的时候就应该清楚,程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的:

1. 让EBP保存ESP的值;

PUSH EBP

MOV EBP, ESP

2. 在结束的时候调用

mov esp, ebp

pop ebp

retn

或者是

leave

retn

两个形式是一个意思。 这样做的好处是不用考虑ESP等于多少,PUSH了多少次,要POP多少次了,因为我们知道EBP里面放的是开始时候的ESP值。

32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP,对低16位数据的存取,不影响高16位的数据。

寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。 指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。

它们主要用于访问堆栈内的存储单元,并且规定:

BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据;

SP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。

只要在[…]中使用寄存器BP,而指令中没有显性地给出段地址,段地址就默认在SS中,比如:

MOV AX , [B] 含义 AX = (SS) * 16 + BP;

BP: 是和堆栈指针SP联合使用的,作为SP校准使用的,只有在寻找堆栈里的数据和使用个别的寻址方式时候才能用到比如说,堆栈中压入了很多数据或者地址,你肯定想通过SP来访问这些数据或者地址,但SP是要指向栈顶的,是不能随便乱改的,这时候你就需要使用BP,把SP的值传递给BP,通过BP来寻找堆栈里数据或者地址.

经验分享 程序员 微信小程序 职场和发展