有关基指针和堆栈指针的问题

时间:2011-10-17 07:16:27

标签: memory-management pointers stack base

我正在编写一份报告来总结堆栈。如果你点击我的个人资料,你会发现我已经这样做了一段时间。现在,我遇到了一些麻烦,因为在GDB上它向我展示了与视觉工作室不同的东西。

因此,我对基本指针和堆栈指针的理解不太确定,我希望如果我错了,有人可以引导我朝着正确的方向前进。

对于x86计算机,堆栈通常会向下增长(从较高的内存地址到较低的内存地址)。

所以当一个程序开始时,我们调用了main函数。

  1. 通常,在每个函数调用的入口处,在当前esp位置创建堆栈,这就是我们所谓的“堆栈顶部”。这是对的吗?

  2. 当旧的ebp被推入堆栈时,它是否被推到esp首次指向的位置?

  3. 之后,esp将向下移动以指向空的内存位置,这是正确的吗?

  4. 最后,esp总是在变化,向下移动指向下一个可用的内存空间。这是对的吗?

  5. esp是按字节移动还是每4字节移动一次?

  6. 我知道有很多问题。但是谢谢你的时间!


    感谢您的回复,先生!

    @iSciurus

    我很困惑每个人如何定义esp指向被推入堆栈的最新条目。

    对于x86,由于堆栈向下增长,根据您的解释,esp将首先指向堆栈的最低地址。当我查看汇编代码时,我们有

       0x080483f4 <+0>: push   %ebp
       0x080483f5 <+1>: mov    %esp,%ebp
       0x080483f7 <+3>: sub    $0x10,%esp
    

    因此esp减少了16个字节。所以这是此函数调用的堆栈的 size 。局部变量在返回地址(ebp-4,ebp-8等)之后。那么esp的总体目标是什么?根据我的理解,当我们尝试访问小于该地址的地址时,会发生堆栈溢出。

    最后一件事是:当我们说堆栈顶部时,我们是指最低地址(对于x86)。

    这是我想到的图片(向下成长)

    [Parameter n          ]
    ...
    [Parameter 2          ]
    [Parameter 1          ]
    [Return Address       ]   0x002CF744
    [Previous EBP         ]   0x002CF740  (current ebp)
    [Local Variables      ]   
    -- ESP
    

    抱歉这些长期问题。但我非常感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

  1. 要正确,在当前esp位置创建堆栈帧,而不是堆栈本身。堆栈在线程启动时创建一次,每个线程都有自己的堆栈,这只是进程内存空间中的一个区域。堆栈帧是在每个函数入口处实际创建的,它是线程堆栈内的一个区域。

  2. 不,它被推送到地址 [old_esp - 4] (或x64中的 [old_rsp - 8] ),因为esp是顶部的堆栈并指向最低使用地址。堆栈中的下一个DWORD(或QWORD)是免费的,并且ebp被推送到那里。

  3. 是的,这通常是通过 sub esp,value

  4. 完成的
  5. 没有。首先,esp向下移动指向堆栈中使用最少的地址,而不是指向下一个可用空间。其次,请记住,esp可能指向任何地方,而不仅仅指向堆栈:在使用与推送/弹出相关的堆栈相关的指令之前,它是可以的。

  6. Esp每个机器字大小移动:在x86中每4个字节移动一次,而在x64中每8个字节移动一次。


  7. esp的总体目的几乎总是相同的:存储堆栈的顶部。所有与堆栈相关的指令(如pop / push)都使用esp作为参数。在x86中,ebp和esp都用于存储有关堆栈帧的信息(相应的底部和顶部)。也许,你对这种冗余感到困惑。但是,在x64中,只有rsp用于基于堆栈的参数,rbp是通用寄存器。

    如果堆栈中的缓冲区溢出怎么样,当代码尝试写入高于数组的最后一个元素(或结构或其他)时,它们经常发生。堆栈向下增长,但阵列向上增长。当我们写得更高时,我们可以访问返回地址,SEH处理程序以及调用者的内部变量。

    是的,当我们说顶部时,我们指的是最低地址。因此,大多数调试器以相反的顺序显示堆栈:

    -- ESP
    [Local Variables      ]
    [Previous EBP         ]   0x002CF740  (current ebp)
    [Return Address       ]   0x002CF744
    [Parameter 1          ]
    [Parameter 2          ]
    ...
    [Parameter n          ]
    

    在这里,ESP指向所有数据“高于”的值,看起来更像是“顶部”。虽然它仍然是使用率最低的地址。