栈帧

栈帧statck frame

  • 用栈帧来分配给每个函数调用分配一段内存
  • ebp为帧指针
  • ebp与esp之间的部分为当前帧



gdb调试中info frame该命令会依次打印出

(gdb) info frame
Stack level 0, frame at 0xbffff640:

当前栈帧的编号,以及栈帧的地址;

 eip = 0x80483ad in main (second.c:16); 

eip即程序计数器,要执行的下一条指令的汇编地址,在second.c的16行执行,即0x80483ad <main+25>        leave

 saved eip 0x237d28

被保存的eip,他是一个返回地址,即从该被调用者堆栈返回后在调用者堆栈帧中来恢复指令,根据CALL指令将其压入堆栈(保存以供返回)。

 source language c.         

编写此栈帧所用的编程语言;

Arglist at 0xbffff638, args:   

函数参数的存储地址以及值,这里为空

 Locals at 0xbffff638,

函数中局部变量的存储地址;

Previous frame's sp is 0xbffff640

前一帧的sp为0xbffff640,这是前一帧的堆栈指针指向(调用者帧)的位置,在调用时,它也是被调用堆栈帧的起始内存地址

 Saved registers:
  ebp at 0xbffff638, eip at 0xbffff63c

栈帧中存储的寄存器变量,例如指令寄存器(64位环境中用 rip 表示,32为环境中用 eip 表示)、 堆栈基指针寄存器(64位环境用 rbp 表示,32位环境用 ebp 表示)等。

上面显示的是两个保存的寄存器在当前帧上即被调用者堆栈上的两个地址。在0xbffff638处的ebp是保存调用者堆栈帧的ebp寄存器的地址(它是寄存器用来存值的地址,而不是调用者的堆栈地址,即对应于 push %ebp

ebp是通常被视为此堆栈帧本地地址的起始地址的寄存器,使用偏移量进行寻址。换句话说,局部变量的操作都使用此ebp,因此会有诸如mov  -0x4(%ebp),%eax等的内容。
同前面的ebp存储一样,在堆栈地址0xbffff63c处存eip的值(其中保存的值为0x1a7d28)

called by frame at 0xbffff624, caller of frame at 0xbffff5ec   

当前函数的调用者,对应的栈帧的地址;

只有main的函数的栈帧分析

debug栈内容查看

  
(gdb) x/8xw 0xbffff628
0xbffff628:     0x080483cb      0x00388ff4      0x00000003      0x00000005
0xbffff638:     0xbffff6b8      0x001a7d28      0x00000001      0xbffff6e4



(gdb) info frame
Stack level 0, frame at 0xbffff640:
 eip = 0x80483a1 in main (second.c:14); saved eip 0x1a7d28
 source language c.
 Arglist at 0xbffff638, args: 
 Locals at 0xbffff638, Previous frame's sp is 0xbffff640
 Saved registers:
  ebp at 0xbffff638, eip at 0xbffff63c


push   %ebp           //保存上一个栈帧的帧指针,并设置当前的指针                                           
movl    %esp, %ebp
subl    $16, %esp

第一行保存旧的 %ebp,此时新的栈空间还没有创建,但保存旧的 %ebp 的这一行空间将作为新栈帧的栈底,也就是帧指针,
因此第二行将栈指针 %esp永远指向栈顶)的值设置到 %ebp 上。 第三行将 %esp 下移 16 个字节,这一行其实就是为函数main开辟栈空间了。(有部分空间未使用,这个是为了地址对齐,不影响我们的分析,可以忽略。)

每个小方格表示4个字节的内存单元

movl    $3, -8(%ebp)
movl    $5, -4(%ebp)
movl    $0, %eax

以%ebp为基址进行偏移寻址写入局部变量a=3,b=5

leave
ret

leave指令相当于下面两条:

movl   %ebp ,%esp //撤销栈空间,回滚%esp。
popl   %ebp      //恢复上一个栈帧的%ebp。

ret指令相当于下面的指令

popl   %eip //恢复指令指针寄存
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值