通过一段汇编,加深对寄存器ESP和EBP的理解

原文: http://blog.youkuaiyun.com/zsJum/article/details/6117043



一直对寄存器ESP和EBP的概念总是有些混淆,查看定义ESP是栈顶指针,EBP是存取堆栈指针。还是不能很透彻理解。之后借于一段汇编代码,总算是对两者有个比较清晰的理解。
下面是按调用约定__stdcall 调用函数test(int p1,int p2)的汇编代码
;假设执行函数前堆栈指针ESP为NN
push   p2    ;参数2入栈, ESP -= 4h , ESP = NN - 4h
push   p1    ;参数1入栈, ESP -= 4h , ESP = NN - 8h
call test    ;压入返回地址 ESP -= 4h, ESP = NN - 0Ch 
;//进入函数内
{
push   ebp                        ;保护先前EBP指针, EBP入栈, ESP-=4h, ESP = NN - 10h
mov    ebp, esp                   ;设置EBP指针指向栈顶 NN-10h
mov    eax, dword ptr  [ebp+0ch]  ;ebp+0ch为NN-4h,即参数2的位置
mov    ebx, dword ptr  [ebp+08h]  ;ebp+08h为NN-8h,即参数1的位置
sub    esp, 8                     ;局部变量所占空间ESP-=8, ESP = NN-18h
...
add    esp, 8                     ;释放局部变量, ESP+=8, ESP = NN-10h
pop    ebp                        ;出栈,恢复EBP, ESP+=4, ESP = NN-0Ch
ret    8                          ;ret返回,弹出返回地址,ESP+=4, ESP=NN-08h, 后面加操作数8为平衡堆栈,ESP+=8,ESP=NN, 恢复进入函数前的堆栈.
}
看完汇编后,再看EBP和ESP的定义,哦,豁然开朗,
原来ESP就是一直指向栈顶的指针,而EBP只是存取某时刻的栈顶指针,以方便对栈的操作,如获取函数参数、局部变量等。
### 汇编代码 'push ebp' 'mov ebp, esp' 的功能及意义 在汇编语言中,`push ebp` `mov ebp, esp` 是用于管理函数调用栈帧的两条重要指令。以下是这两条指令的具体功能意义: #### 1. `push ebp` 这条指令的作用是将当前的基址指针(ebp)值压入栈中[^4]。这一步是为了保存当前函数的旧栈帧顶部地址,以便在函数返回时能够恢复原来的栈帧。由于栈是向低地址增长的,因此执行这条指令后,栈指针(esp)会向下移动4个字节(在32位系统中),以容纳新压入的ebp值。 #### 2. `mov ebp, esp` 这条指令的功能是将栈指针(esp)的值赋给基址指针(ebp)[^1]。这样做的目的是定义一个新的栈帧。此时,ebp指向当前栈帧的顶部,而esp则可以继续向下移动,为局部变量分配空间。通过这种方式,ebp成为了一个固定的基准点,用于访问当前函数的参数局部变量。 #### 示例代码解释 以下是一个典型的函数调用汇编代码片段: ```assembly push ebp ; 保存旧的ebp值到栈中 mov ebp, esp ; 将esp赋值给ebp,定义新的栈帧 sub esp, 0C0h ; 为局部变量分配堆栈空间 ``` - 第一条指令 `push ebp` 将旧的ebp值压入栈中,保存当前栈帧的顶部地址。 - 第二条指令 `mov ebp, esp` 定义了新的栈帧,使得ebp指向当前栈帧的顶部。 - 第三条指令 `sub esp, 0C0h` 为局部变量分配了0Ch字节的空间[^2]。 通过这些操作,函数可以安全地访问其参数局部变量,并在函数结束时恢复原来的栈帧。 ### 相关寄存器的作用 - **ESP(Stack Pointer)**:始终指向栈顶,随着数据的压栈弹栈动态变化[^3]。 - **EBP(Base Pointer)**:用于标记当前栈帧的顶部,在函数调用期间保持不变,方便访问参数局部变量。 ### 注意事项 当函数执行完毕时,需要恢复原来的栈帧。这通常通过以下步骤完成: 1. 将esp恢复到ebp的位置(即恢复栈指针)。 2. 弹出保存的ebp值,恢复上一层函数的栈帧。 #### 示例代码(函数退出时的栈帧恢复) ```assembly mov esp, ebp ; 恢复esp到原来的值 pop ebp ; 恢复ebp到上一层函数的值 ret ; 返回到调用者 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值