EBP ESP 与 CAL

EBP 栈底指针(会随进入不同的函数而改变, 更喜欢手动改变, 自动的有时会画蛇添足)

ESP栈顶指针(永远指向栈顶)

CAL调用函数(隐含操作是将EIP的值入栈, 并将EIP设置为CALL指向的地址)

示例:
  main()函数中的EBP = ESP = 12FF7C

void fun2(int a, int b)

{

int x = a;

int y = b;

}

调用fun2()时,   首先入栈的数据是:fun2()的两个形参a,b(cdecl先将b入栈),       ESP+8

再将fun2()返回后的,EIP的值0040104B入栈                                               ESP+4

再将EBP入栈,保存main()中EBP的值以便fun2()返回后正确使用栈.                   ESP+4

再MOV EBP, ESP 设置fun2()内部的EBP                                                EBP=ESP

再SUB ESP, 8 给fun2()函数内的两个临时变量分配栈空间                          ESP-8

再MOV ESP, EBP 将ESP复位                                                                  ESP=EBP(考虑是否可以ADD ESP, 8)

再POP EBP 恢复EBP原值, 即12FF7C                                                        ESP+4

最后, RETN也触发一次POP操作,即ESP的值增加了, 恢复到0012FF7C.              ESP+4

返回到main()后, 还需要ADD ESP, 8  这点需要留意, 以便恢复调用fun2()前, ESP的值

进入fun2()函数后,反汇编如下:

PUSH EBP

MOV EBP, ESP

SUB ESP, 8

MOV DWORD PTR SS:[EBP-4], 3

MOV DWORD PTR SS:[EBP-8], 4

MOV ESP, EBP

POP EBP

RETN

时间: 2024-10-18 21:21:28

EBP ESP 与 CAL的相关文章

汇编之 eax, ebx, ecx, edx, esi, edi, ebp, esp??

一般寄存器:AX.BX.CX.DXAX:累积暂存器,BX:基底暂存器,CX:计数暂存器,DX:资料暂存器 索引暂存器:SI.DISI:来源索引暂存器,DI:目的索引暂存器 堆叠.基底暂存器:SP.BPSP:堆叠指标暂存器,BP:基底指标暂存器 EAX.ECX.EDX.EBX:為ax,bx,cx,dx的延伸,各為32位元ESI.EDI.ESP.EBP:為si,di,sp,bp的延伸,32位元 eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU

堆栈中的EIP EBP ESP

EIP,EBP,ESP都是系统的寄存器,里面存的都是些地址. 为什么要说这三个指针,是因为我们系统中栈的实现上离不开他们三个. 我们DC上讲过栈的数据结构,主要有以下特点: 后进先处.(这个强调过多) 其实它还有以下两个作用: 1.栈是用来存储临时变量,函数传递的中间结果. 2.操作系统维护的,对于程序员是透明的. 我们可能只强调了它的后进先出的特点,至于栈实现的原理,没怎么讲?下面我们就通过一个小例子说说栈的原理. 先写个小程序: void fun(void) { printf("hello

函数参数压栈,栈帧ebp,esp怎样移动的?

压栈一次esp-4,ebp不变 esp是栈顶指针寄存器,堆栈操作只和esp有关比如有一个函数a,有两个参数,一般是这样的PUSH 1 参数2压栈,esp-4PUSH 2 参数1压栈,esp-4CALL a 调用 a:PUSH EBP 保存ebpMOV EBP,ESP 改变栈帧,以后访问参数通过ebp,访问局部变量通过espSUB ESP,8 分配局部变量空间 ...ADD ESP,8POP EBP 恢复ebpRETN 8 返回,esp+8 C语句对应汇编语句: 例如函数: int aaa(int

寄存器简介 与 ebp esp

http://www.cnblogs.com/zhuyuanhao/archive/2012/10/16/3262870.html 32位CPU所含有的寄存器有:4个数据寄存器(EAX.EBX.ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES.CS.SS.DS.FS和GS)1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)

函数调用(ebp,esp,堆栈快照)

概率 esp :栈顶指针,必须的 ebp:  存放堆栈指针,不是必须的 #include <stdio.h> int func(int param1 ,int param2,int param3) { int var1 = param1; int var2 = param2; int var3 = param3; printf("var1=%d,var2=%d,var3=%d",var1,var2,var3); return var1; } int main(int arg

EBP的妙用[无法使用ESP定律时]

1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等.在win32的环境下EBP寄存器用与 存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的. 应用以前说过的一段话: 原程序的OEP,通常是一开始以 Push EBP 和MOV Ebp,Esp这两句开始的,不用我多说大家也知道这两句的意思是以EBP代替E

C++代码反汇编后的堆栈寄存器EBP和ESP

最近在分析一个进程崩溃的严重问题,其中有些过程分析需要对ebp, esp 有清晰的理解,对于ebp 和esp 相信大家都很熟悉了,但是为了使本文自成体系,我还是解释一下. ebp--栈底指针 esp--栈顶指针 如图所示,简化后的代码调用过程如下: void Layer02() { int b = 2; } void Layer01() { int a = 1; Layer02(); } 那么函数执行过程中ebp和esp是如何变化的呢?如下是反汇编后的代码: void Layer02() { 0

esp寻址ebp寻址

栈顶指针esp 栈底指针ebp esp寻址 构建函数 1.使用寄存器传递参数 2.使用堆栈来传递参数 push 1 push 2 push 3 把要用的参数压入堆栈后,需要用call调用函数来计算参数,调用call时,会将call的下一行指令的地址压入栈中,所以使用参数时地址为[esp+4,8,12] 使用函数的代码为 mov eax,ptr ss:[esp+4] add eax,ptr ss:[esp+8] add eax,ptr ss:[esp+12] retn 12   //保持堆栈平衡

基于EBP的栈帧

程序的OEP,一开始以 push ebp 和mov ebp esp这两句开始. 原因:c程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的: 1.让EBP保存ESP的值. 2.在程序运行完毕的时候调用 mov esp,ebp pop ebp retn 或者是 leave retn 通过EBP保存程序运行前ESP的值,那么程序运行过程中,不管ESP被Push还是Pop多少次,最终都可以通过EBP还原最开始