当前位置: 首页 > 编程技术 > 正文

关于EBP寄存器的作用

EBP寄存器在汇编语言中较多的使用到,比如在一个程序反汇编后,你会发现每当程序进入一个CALL,进入了后,做的第一件事基本上都是下面的两行代码:

PUSH EBP //保存老的帧指针
MOV EBP,ESP  //赋给新的帧指针

那么为什么反汇编后,基本上所有的子程序都是以 push ebp , mov ebp,esp开始呢?

首先要明白的是堆栈这个东西,堆栈是一种数据结构,具有先进后出的特点,因为堆栈的这个特殊的特点,在汇编语言中,常常用到堆栈来保存数据

比如反汇编中经常会出现下面的代码:

CALL DWORD PTR DS:[<&KERNEL32.VirtualFree>]              ;

通过OD反汇编我们发现程序反汇编后会有很多的call,而这些call的作用和C语言中的函数调用是类似的

如果你对c语言研究的比较深或者是比较熟悉的话,那么你一定知道当一个函数调用并返回后,程序会接着执行下一条语句,不如下面的代码

void fun(){

	cout<<"hello world !"<<endl;
	return ;

}
int main(int argc,char argv[]){
	int x;
	fun();
	x = 1;
	return 0;
}

当程序遇到fun时,程序会执行fun的内容即输出helloworld,fun函数返回后,程序跳到x =1,这一句继续执行,那么程序是怎么知道要返回到那么呢?这里就用到了stack,程序在调用时,将下一条的指令的地址压栈,如果是跨段调用的话,还要保存cs的值,因此c语言里面的函数调用类似于汇编里面的call

而在汇编中,call等同于下面的命令:

//远call
push CS
push EIP
JMP far ptr
//近call
push EIP
JMP far ptr

因此堆栈的作用是很大的,当程序retn时,依次恢复原来的值,程序继续执行下一句

这里EBP的作用就是保存SP的值,

还是以上面的程序为例

void fun(){

	cout<<"hello world !"<<endl;
	return ;

}
int main(int argc,char argv[]){
	int x;
	fun();
	x = 1;
	return 0;
}

因为程序一旦装入内存,操作系统就会分配空间,程序可以将操作系统分配的空间的一段空间作为栈来使用,但是这个栈的空间一般都是固定的,不论是你指定还是操作系统默认,也就是说,程序的所有函数都共用一段内存,那么问题就来了,当一个子程序需要访问栈的时候,他怎么访问呢,使用SP+偏移吗?因为SP始终指向栈的顶部,这样的话,栈的顶部的地址是有可能要变的,那么怎么刚刚压栈的值呢?这里既要用到EBP了

我们知道栈的大小是固定了的,那么可以将栈动态的划分给每个子程序吗?答案是可以的,
这里假设执行fun()函数时EBP == x,那么进入到fun函数时,又要读取或者是使用ebp怎么办,尤其是修改EBP的值,那么就可以在每个子程序执行时,把EBP的值如栈,等到程序返回时,把EBP弹栈就可以继续使用EBP了,而不用担心EBP的值被篡改

程序在跳到fun之程序时,假设EBP == x.SP = y,那么执行了:

PUSH EBP
MOV EBP,ESP

后,main的EBP就保存了,保存的地址就在SS*16+ESP里面,这个时候,因为ESP的值已经减去4(16位是减去2)了就有y = y-4,这个时候把ESP赋给EBP,就相当于将EBP的值最为新的栈底,那么通过EBP来实现子程序的栈的寻址就可以避免了ESP的改变来影响寻址的数据的正确性了,

所以EBP就相当于子程序的的新的栈底了,使用EBP可以动态的使用栈而不用栈的全局寻址了

综上所诉,

假设上面的程序,main的”栈底”EBP的值为x,SP的指针的值为y,那么执行到fun时,
EBP= y-4(因为push ebp占用了4个字节的空间,那么Mov EBP,ESP就有了EBP= y-4),那么y-4的值就是fun的新的“栈底”了
ESP= Y-4
在Y-4到Y的地址空间上保存了main函数的”栈底”的值,
地址为Y就是main函数暂时的栈顶了

那么EBP的作用很明显了,他的作用如他的解释一样(基址寄存器,)用于在”每个子程序的所属的动态堆栈”中相对寻址,具体来说就是对子函数的变量进行寻址(注意是作用域为子函数的变量,而不是全局变量,ebp通常为基质,后面加上具体的偏移即可寻址了)

如果还不太清楚的话,参考这篇文章:举例说明EIP,EBP,ESP的作用



本文固定链接: http://kuaile.in/archives/714 | 蒲公英的博客

该日志由 蒲公英 于2012年03月24日发表在 编程技术 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 关于EBP寄存器的作用 | 蒲公英的博客
关键字:

关于EBP寄存器的作用:等您坐沙发呢!

发表评论


You must enable javascript to see captcha here!

快捷键:Ctrl+Enter