关于这个主题有很多主题,但在找到的所有主题中找不到我想要的答案。
我的实际问题是:
当我们进入程序时,我们使用函数prologues和epilogue(ENTER和LEAVE指令)以保持程序正常运行而不会发生任何泄漏。
假设您的工作中需要2个局部变量。您可以将ESP减少8,将对齐默认为4个字节(DWORD)。在此过程结束时,您希望 DESTROY / RELEASE 这些变量,因此您必须将ESP设置为EBP。
我的问题是,ESP地址的变化如何等于EBP地址会破坏/释放局部变量?我们打电话给RET后会发生什么?堆栈框架是如何被破坏的?
答案 0 :(得分:2)
第一个问题:ESP
是指向堆栈顶部的指针,因此如果在过程结束时向ESP
添加8,则会减少堆栈。存储在本地字段中的内存不再存在于堆栈中,因此可以根据需要进行更改。第二个问题:RET
命令执行两项操作:它将控件返回给主程序,但是以更技术的方式 - 它从堆栈顶部读取数字并将其写入EIP
寄存器这是指令指针。
还值得知道CALL
指令执行两项操作 - 它将下一个订单的地址推送到堆栈,然后跳转到该过程 - 这意味着RET
知道跳转到哪里< / p>
答案 1 :(得分:2)
函数的结尾如下所示:
mov %esp, %ebp
pop %ebp
ret
或(在x86中,其中leave与上面的前两行相同)
leave
ret
回答你的问题:
- 在指令离开的第一部分,我们将de%ebp设为等于%esp
- 我们称之为“ret”,通过弹出堆栈顶部,将PC(程序计数器)的值设置为“调用”指令旁边的指令地址。
- 当我们将新值设置为%esp(%esp + 4)
时,堆栈帧被“销毁”