Post on: 2024-6-20Last edited: 2024-7-23Words 00 min

type
status
date
slug
summary
tags
category
icon
password

栈帧

简言之,栈帧就是利用EBP(栈指针,请注意不是ESP)寄存器访问内局部变量、参数 函数返回地址等的手段。通过前面关于IA-32寄存器的学习我们知道,ESP寄存器承担着栈顶指针
进入main函数和main函数快要结束的时候rsp和rbp是怎么变化的
在进入 main 函数和快要结束 main 函数时,rsp(栈指针寄存器)和rbp(基指针寄存器)的变化情况如下:

进入 main 函数时:

在 main 函数的开头,标准的函数序言会调整栈指针和基指针,以设置新的栈帧并保护旧的栈帧。这通常遵循以下步骤:
保存旧的基指针: ◦ pushq %rbp 将当前的基指针 rbp 的值推入栈中,以便稍后恢复。设置新的基指针: ◦ movq %rsp, %rbp 将当前的栈指针 rsp 的值复制到 rbp 中。此时,rbp 的值成为新的栈帧的基地址。空间分配: ◦ subq $48, %rsp 调整栈指针 rsp,为局部变量或其他用途分配48字节的空间。

汇编代码示例:

进入 main 函数时 rsp 和 rbp 的变化:

进入之前: ◦ 假设 rsp = 0x7fffffffe0f0 ◦ 假设 rbp = 0x7fffffffe100pushq %rbp 之后: ◦ rsp 会减少 8 字节(x86-64 平台),rsp = 0x7fffffffe0e8rbp 不变movq %rsp, %rbp 之后: ◦ rbp 现在指向新的栈帧基地址,rbp = 0x7fffffffe0e8subq $48, %rsp 之后: ◦ rsp 会减少 48 字节,rsp = 0x7fffffffe0b8rbp 不变

快要结束 main 函数时:

在 main 函数结束前,标准的函数尾声会恢复旧的栈帧并返回调用函数。通常遵循以下步骤:
恢复栈指针: ◦ addq $48, %rsp 将栈指针恢复到调用之前的位置。恢复旧的基指针: ◦ popq %rbp 从栈中弹出旧的基指针值,并恢复到 rbp

汇编代码示例:

快要结束 main 函数时 rsp 和 rbp 的变化:

开始恢复前: ◦ rsp = 0x7fffffffe0b8rbp = 0x7fffffffe0e8addq $48, %rsp 之后: ◦ rsp 会增加 48 字节,rsp = 0x7fffffffe0e8rbp 不变popq %rbp 之后: ◦ rsp 会增加 8 字节,rsp = 0x7fffffffe0f0rbp 恢复到之前的值,假设恢复到 0x7fffffffe100
总结:
进入 main 函数时:
rsp 从原位置减少 8 字节保存 rbp,然后减少 48 字节为局部变量分配空间。rbp 从原位置设置成与 rsp 开头相同。
快要结束 main 函数时:
rsp 回升 48 字节,恢复到进入 main 函数时的状态。rbp 被恢复到调用者保存的旧值。
这两个寄存器的变化展示了栈帧的创建和恢复过程,这是大多数函数调用遵循的标准协议。

删除栈帧&main()函数终止

 

idapython浅学习

🗒️idapython浅学习

学一学idapython


hgame2024re

🗒️hgame2024re

hgame2024re