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