首页 新闻 会员 周边 捐助

函数调用寄存器

0
[已关闭问题] 关闭于 2025-08-11 14:52

旧 EBP 保存的是 caller 的栈帧基址;
mov ebp, esp 之后,EBP 变成了 callee 的新栈帧基址(通常是 ESP 当时的值,也就是旧 EBP 所在地址
地址不是一样吗,也就是旧 EBP 所在地址这句话不就说是一样的地址吗

_java_python的主页 _java_python | 小虾三级 | 园豆:984
提问于:2025-08-11 14:51
< >
分享
所有回答(1)
0

旧 EBP 里存放的数值
这个数值是 caller 的栈帧基址(例如 0x1000)。
它代表“caller 的栈底”。
旧 EBP 本身所在的位置
push ebp 把数值 0x1000 写到了 某个栈地址(例如 0x0FFC)。
随后 mov ebp, esp 把寄存器 EBP 改成 0x0FFC——这是 callee 的新栈帧基址。
所以:
数值 0x1000 ≠ 位置 0x0FFC
旧 EBP 保存的是 数值(caller 基址),
新 EBP 保存的是 位置(旧 EBP 所在的栈地址),二者不同。
push ebp 只是把旧值临时存到栈里,随后 mov ebp, esp 把寄存器 EBP 重新赋成新值。
函数返回时 pop ebp 又把栈里的旧值弹回寄存器——寄存器还是那个寄存器,只是内容被换了一次。
caller 和 callee 都在同一个进程的虚拟地址空间里,所以所谓“旧 EBP 地址”和“新 EBP 地址”只是同一块内存里的不同偏移量。
它们虚拟地址范围不同。
caller 的栈帧用一段地址(比如 0x1000–0x101C),callee 的栈帧往下再开一段(比如 0x0FFC–0x0FE4)。
虽然同属同一个进程的虚拟地址空间,但具体区间随着函数调用/返回而动态变化,他们的ebp基地址肯定也不一样。
• 旧 EBP 的值 = caller 的栈帧基址(例:0x1000)
• 新 EBP 的值 = callee 的栈帧基址(例:0x0FFC)
这两个值必然不同,只是都落在同一进程的虚拟地址空间里
EBP 寄存器本身只有一份,但在整个函数执行期间它的值是固定不变的;
当函数返回时,通过 leave/pop ebp 把它恢复成调用者的旧值
函数返回后,原来的 ebp 值被弹回寄存器,于是下一层被调函数(下一个 callee)的 prologue 再次把它“借”过来,继续当自己的栈帧基址指针

在 当前 callee 的生命周期内,EBP 寄存器的值焊死在 callee 自己的栈帧基址上,保持不变;
只有 函数返回 时,通过 leave/pop ebp 把它恢复成 caller 的旧值,下一帧再重新“焊死”在新的基址上。
是 寄存器里“存的值”焊死,不是寄存器硬件本身焊死。
EBP 还是那 32/64 位物理寄存器,只是在当前函数执行期间,它的比特内容保持为callee 的栈帧基址不变

_java_python | 园豆:984 (小虾三级) | 2025-08-11 14:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册