Assembly 为什么功能结束时需要mov rbp和rsp
我理解函数序言:Assembly 为什么功能结束时需要mov rbp和rsp,assembly,x86,Assembly,X86,我理解函数序言: push %rbp mov %rsp, %rbp 例如,如果我们想使用rbp作为本地函数stackframe的参考点,那么我们需要: 将rbp设置为堆栈指针的当前位置 恢复末尾的rbp值,因为rsp、rbp已被调用方保存 由此,我开始: push %rbp # save this onto the stack so we can restore it back at the end mov %rsp, %rbp # now we can use rbp
push %rbp
mov %rsp, %rbp
例如,如果我们想使用rbp
作为本地函数stackframe的参考点,那么我们需要:
- 将
设置为堆栈指针的当前位置rbp
- 恢复末尾的
值,因为rsp、rbp已被调用方保存rbp
push %rbp # save this onto the stack so we can restore it back at the end
mov %rsp, %rbp # now we can use rbp as our 'local stack'
...
pop %rbp # restore the rbp value
但是,为什么结尾处有必要添加mov%rbp,%rsp?通常情况下,它似乎已经与
rbp
具有相同的值。或者,仅当我执行额外的推送
,弹出
,或添加/订阅%rsp
,这才有必要吗?查看实际使用堆栈空间进行局部搜索的函数。在mov%rsp,%rbp
之后将立即出现sub$NNN、%rsp
,最后的mov%rsp、%rbp
将有效地撤消该操作,以将堆栈放回原来的位置。在这种情况下,一个简单的添加$NNN,%rsp
也就足够了,但是一个更复杂的函数可能会通过非恒定量(例如,对于VLA或alloca
)多次调整堆栈,在这种情况下,跟踪它们将是一件痛苦的事情all@NateEldredge哦,我明白了,所以只有在修改内部堆栈框架时才需要它,是吗?是的,这就是为什么GCC实际上会在除了通过push RSP之外不会改变的函数中省略它(只使用pop%rbp
)。leave
指令与mov RSP,rbp;弹出rbp
。以便恢复rbp,以便被调用函数继续使用。