学习 x86 汇编和帧指针让我有点吃惊。我从这个SO question中了解到,EBP 让调试变得很棒。这很好,但我很好奇,“EBP 还有什么用途?” 查看调用堆栈Wikipedia 文章,EBP 是动态堆栈分配所必需的。
正如我一直假设动态分配在堆上进行的那样。那么,我为什么要使用动态堆栈分配——为什么堆还不够好?而且,EBP 对此有何用处?
学习 x86 汇编和帧指针让我有点吃惊。我从这个SO question中了解到,EBP 让调试变得很棒。这很好,但我很好奇,“EBP 还有什么用途?” 查看调用堆栈Wikipedia 文章,EBP 是动态堆栈分配所必需的。
正如我一直假设动态分配在堆上进行的那样。那么,我为什么要使用动态堆栈分配——为什么堆还不够好?而且,EBP 对此有何用处?
您错误地假设ebp
堆栈帧分配是必需的。这不是真的,esp
可以直接使用。现在完全没有必要将其ebp
用作堆栈帧指针。有几点是有用的:
在 16 位代码中,sp
(堆栈指针)在寻址中的使用受到严重限制,在 x86 中根本不可能直接使用相对寻址,可以在所有bp
可用的寻址模式中使用。
这种有限支持的原因可能是当时可用的编译器,使用帧指针生成代码然后跟踪不断变化的sp
. 还有更多的处理器对堆栈帧指令有特殊的支持,比如leave
or enter
,但是 AFAIK 除了英特尔之外没有其他人已经sp
在这个过程中削弱了现实:-)
调试。当帧指针可用时,展开堆栈要容易得多,但现代调试器甚至可以做到。
如果要在堆栈上分配 100 字节空间,只需执行sub esp, #100
,访问move [esp + x]
wherex
介于 0 和 99 之间的空间并清理,add esp, #100
就完成了。我什至会争辩说,在手写汇编中使用堆栈帧指针就像复制一个有 30 年历史的编译器的行为,当时编译器真的很愚蠢,不能没有。如果您正在编写汇编,那么它既没有必要也没有用。
与堆分配相比,从堆栈分配少量内存非常快。当我们从堆中分配内存时,我们必须调用 API 或内存管理器。
是的,您也可以将 EBP 寄存器用于任何其他目的,例如其他 32 位寄存器,但您必须首先存储其内容,然后在退出程序之前恢复。
您可以PUSH EBP
用于将 EBP 内容存储到堆栈和POP EBP
用于恢复。