我有两个关于EBP注册的问题.
我理解ESP和EIP.但是,我真的不明白为什么会使用EBP.
在下面的代码中,我将EBP寄存器(实际上是0000000)推送到堆栈.然后,我将堆栈的内存地址移动到EBP,以便ESP和EBP具有相同的数据.这是序言.有一些代码用syscall完成.然后我做反向(epilog),因为’leave’表示我将EBP移动到ESP(这些值与prolog相同)然后将堆栈的最后一个值(即EBP,即00000000)弹出到EBP.这使得EBP与prolog之前的值相同.
为什么有人会这样做?有什么意义?请以简单的方式回答!请记住,我没有掌握EBP(帧指针)实际上做了什么.
编辑:或者这是一种在函数中有效备份堆栈(ESP)的方法吗?换句话说:程序可以执行它对堆栈的操作,并且’原始堆栈’将始终存在于EBP中.然后,当程序结束时,EBP将重新回到之前的状态.它是否正确?如果是这样,epilog只是一个整理程序?
另外,AIUI,我可以用’enter’代替’push ebp / mov ebp,esp’.然而,当我尝试在nasm中编译时,我得到’错误:操作码和操作数的无效组合”离开’工作正常; ‘enter’没有.什么是正确的语法?
谢谢!
Example:
push ebp
mov, ebp, esp
[some code here]
int 0x80
leave
ret
最佳答案 EBP形成堆栈中变量的固定引用点:主要是函数的所有参数,函数的所有本地参数以及最后的返回地址.使用此固定点,函数几乎可以随机地增大/改变它的堆栈,从任何地方跳转到函数结尾,并将堆栈指针恢复到原始位置.
这个概念紧挨着强制性,因为原始的8086代码不允许堆栈指针与mov ax,[sp 10]中的位移一起使用,但仅限于push和pop.除了使用mov xx,[bp 10]完成顶部元素之外的任何其他内容.