【问题标题】:What is the value of esp after a function returns?函数返回后esp的值是多少?
【发布时间】:2016-10-28 13:37:34
【问题描述】:

在 C/x86 中,从函数返回时,我们通常:

  1. pop ebp恢复之前函数的帧指针
  2. ret 其中(据我了解)包含一个隐式的 pop eip 以便调用函数可以从返回地址继续执行

此时,我期望 esp 包含什么?它是指向直接高于返回地址的指针,还是 esp 的值也被ret 隐式更改?

谢谢:)

【问题讨论】:

  • 在 CDECL 调用约定中,esp 现在将指向调用前压入堆栈的最后一个参数。
  • 对于此类进一步的问题,您可能需要阅读手册,其中包含对每条指令作用的非常详细的解释。
  • @CodyGray: ret 确实会影响 esp:它会像 OP 所说的那样弹出返回地址。正确的说法是调用/返回对不会影响堆栈(假设调用约定是调用者弹出 args,而不是使用 ret imm16 的被调用者)
  • 呃,错字!意思是说。谢谢@彼得

标签: c assembly x86 nasm


【解决方案1】:

它是指向直接高于返回地址的指针,还是 esp 的值也被 ret 隐式更改?

ret 有两种形式:retret N。第一种形式只是从堆栈中弹出 eip(通常意味着“获取 eip 并添加 esp,4”)并继续执行,因此 esp 指向调用函数时推送的最后一个参数 - 这意味着调用者必须通过以下方式处理此问题后续add esp, N

ret N 表示弹出 eip 后,esp 在同一条指令中加上值 N,因此调用者无需这样做。缺点是不能使用可变数量的 args,因为 'N' 只能是常数值。

【讨论】:

    【解决方案2】:

    在 ret 之后,sp 应该与函数调用发生时相同。

    所以它会指向最后推入堆栈的任何内容。

    【讨论】:

      【解决方案3】:

      ret 之后,esp 应该包含与对应的call 之前相同的值,如果两者之间没有发生任何恶作剧的话。 call 指令将返回值压入堆栈,ret 指令将其弹出。所以是的,你的直觉是正确的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        相关资源
        最近更新 更多