在函数调用期间递减ESP

时间:2015-05-06 03:25:48

标签: c assembly intel

我反汇编了一个小程序,要求用户输入他们的名字,然后输出“你好+ [用户名]”

这是反汇编的输出:

主要功能:

Main function

说出你好的功能:

Say hello function

我注意到,对于function verifyCredentials(req, res, next) { User.findOne({username: req.body.username}, function(err, user) //query Mongo { if(user === null) { return next(new Error('Username does not exist in database')); } else { user.comparePassword(req.body.password, function(err, match) { if(match) { next(null, {id: username, name: username}); } else { next(new Error('not match')); } }); } }); } app.post('/login', verifyCredentials, authRoutes.loginCheck); 函数,ESP寄存器按Ox10递减,对于main()函数,ESP寄存器递减0x20。为什么会这样?

仅供参考:我的处理器是1.4 GHz Intel Core i5,我正在运行OSX

原始C代码:

say_hello()

3 个答案:

答案 0 :(得分:2)

它在堆栈上为局部变量分配空间。第一个BP它设置为SP的当前值,然后SP递减,以便为函数使用的局部变量腾出空间。如您所见,稍后[ss:rbp + ???]用于访问此保留空间的部分内存。

这与在堆栈上重复推送一些虚拟值基本相同。

在函数离开之前,确切的数量被添加回SP是至关重要的,否则RET指令将使用错误的返回地址,程序很可能会崩溃。

答案 1 :(得分:2)

通过堆栈指针“实现”堆栈,堆栈指针指向堆栈段。每次在堆栈上推送一些东西(通过pushl,call或类似的堆栈操作码),它就会写入堆栈指针指向的地址,并且堆栈指针递减( 堆栈正在增长)向下,即较小的地址 )。当您从堆栈中弹出一些东西(popl,ret)时,堆栈指针会递增,并从堆栈中读取值。

对于不同的函数调用,我们为堆栈中的局部变量保留空间,因此我们减少它并获得空间。这通常使用prologue and epilogue完成。

<强>序言

如果体系结构具有基指针(也称为帧指针)和堆栈指针,则函数序言通常执行以下操作(以下操作可能不适用于缺少基指针或堆栈指针的那些体系结构) :

  • 将旧的基本指针推送到堆栈上,以便以后可以恢复(通过获取在下一步中设置的新基本指针值并始终指向此位置)。
  • 将堆栈指针的值(指向保存的基本指针和旧堆栈帧的顶部)分配到基本指针中,以便在旧堆栈帧的顶部创建新的堆栈帧(即顶部旧堆栈框架将成为新堆栈框架的基础。)
  • 通过减少或增加其值来进一步移动堆栈指针,具体取决于堆栈是向下还是向上增长。在x86上,堆栈指针被减少以为变量腾出空间(即函数的局部变量)。

<强>后记

函数结尾会反转函数序言的动作并将控制权返回给调用函数。它通常执行以下操作(此过程可能因架构而异):

  • 使用当前基本(或帧)指针替换堆栈指针,以便在序言之前将堆栈指针恢复为其值
  • 将基指针弹出堆栈,因此在序言
  • 之前将其恢复为其值
  • 返回调用函数,方法是将前一帧的程序计数器从堆栈中弹出并跳转到它

答案 2 :(得分:0)

据我所知,这种减少主要用于&#34;保留&#34;放在堆栈上或保证内存对齐。

What does it mean to align the stack?