【发布时间】:2014-03-19 19:35:50
【问题描述】:
我有两个关于 EBP 注册的问题。
我了解 ESP 和 EIP。但是,我真的不明白为什么要使用 EBP。
在下面的代码中,我将 EBP 寄存器(实际上是 0000000)压入堆栈。然后我将堆栈的内存地址移动到 EBP,以便 ESP 和 EBP 具有相同的数据。这是序言。有一些代码以系统调用结束。然后我做相反的事情(结语),因为“离开”表示我将 EBP 移动到 ESP(由于序言,这些值是相同的)然后将堆栈的最后一个值(即 EBP,即 00000000)弹出到 EBP。这使 EBP 的值与 prolog 之前发生的值相同。
为什么会有人这样做?重点是什么?请用简单的方式回答!请记住,我不了解 EBP(帧指针)的实际作用。
编辑:或者这是一种在函数中有效备份堆栈(ESP)的方法?换句话说:程序可以做它对堆栈所做的事情,并且“原始堆栈”将始终存在于 EBP 中。然后当程序结束时,EBP 会恢复到之前的状态。它是否正确?如果是这样,结语只是一个整理程序?
另外,AIUI,我可以使用 'enter' 来替换 'push ebp / mov ebp, esp'。然而,当我尝试在 nasm 中编译时,我得到“错误:操作码和操作数的无效组合”“离开”工作正常; “进入”没有。正确的语法是什么?
谢谢!
Example:
push ebp
mov, ebp, esp
[some code here]
int 0x80
leave
ret
【问题讨论】:
-
你缺少的叫做stack frame。
-
enter的语法是enter 0, 0。第一个参数是为局部变量(sub esp,???)保留的字节数。第二个参数是“lex level”——你不想知道,就让它为零。 -
永远不要使用
enter。与push/mov相比,它非常慢,并且如果您还可以替换sub esp, imm以保留一些堆栈空间,则只能节省一点代码字节。它比 push / mov 更大(32b)或相同大小(64b)。leave没有潜在的疯狂 CISC 语义,所以它并不慢,值得在一些微架构上使用。
标签: assembly