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

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

因此,我不太了解我对基本指针和堆栈指针的理解,而且我希望如果我错了,有人能够带领我走向正确的方向。

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

所以当一个程序开始时,我们称之为主函数。

  • 通常,在每个函数调用的入口处,在当前esp位置创建一个堆栈,这就是我们所说的“栈顶”。 它是否正确?

  • 当旧的ebp被推入堆栈时,它是否被推到了esp第一次指向的地方?

  • 之后,esp会向下移动,指向一个空的内存位置,对吗?

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

  • ESP每个字节移动,还是每4个字节移动一次?

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


    谢谢你的回应,先生!

    @iSciurus

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

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

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

    所以esp减少了16个字节。 所以这是这个函数调用堆栈的大小 。 局部变量紧接在返回地址后面(ebp-4,ebp-8等)。 那么esp的总体目标是什么? 据我所知,当我们试图访问比这个更小的地址时,会发生堆栈溢出。

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

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

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

    对不起,这些很长的问题。 但我真的很感谢你的帮助。


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

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

  • 是的,这通常是通过sub esp,value来完成的

  • 不。首先,esp正在向下移动,指向堆栈中使用的最低地址,而不是下一个可用空间。 其次,请记住,esp可以指向任何地方,不仅可以指向堆栈:直到使用堆栈相关的指令(如push / pop)才可以。

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


  • 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指向所有数据的“高于”值,看起来更像“顶部”。 虽然它仍然是使用最少的地址。

    链接地址: http://www.djcxy.com/p/80383.html

    上一篇: Questions regarding base pointer and stack pointer

    下一篇: Assistance to draw a stack using C code and assembly code