【问题标题】:How is return address specified in stack?堆栈中如何指定返回地址?
【发布时间】:2011-02-02 07:57:28
【问题描述】:

这是我通过反汇编看到的声明function(1,2,3);

movl   $0x3,0x8(%esp)
movl   $0x2,0x4(%esp)
movl   $0x1,(%esp)
call   0x4012d0 <_Z8functioniii>

好像ret地址根本没有入栈,那么ret是怎么工作的呢?

【问题讨论】:

    标签: assembly x86 stack calling-convention


    【解决方案1】:

    在 x86 处理器上(就您的汇编语言示例而言),call 指令将返回地址压入堆栈并将控制权转移给函数。

    所以在进入函数时,堆栈指针指向返回地址,准备好让ret 将其弹出到程序计数器(EIP / RIP)中。


    并非所有处理器架构都将返回地址放在堆栈上——通常会有一组一个或多个寄存器设计用于保存返回地址。在 ARM 处理器上,BL 指令将返回地址放入特定寄存器(LR,或“链接寄存器”)并将控制权转移给函数。

    ia64 处理器做了类似的事情,除了有几个可能的寄存器 (b0-b7) 可以接收返回地址,并且将在指令中指定一个(b0 是默认值)。

    【讨论】:

      【解决方案2】:

      理想情况下,call 语句应该解决这个问题。程序计数器的下一个位置将被压入堆栈。当被调用的函数(子例程)完成它的工作并遇到返回语句时,控件现在转到被压入堆栈的地址,它将被弹出。

      【讨论】:

      • call是怎么处理的呢?我只想看看ret地址在哪里指定
      • 您将把调用方法分解为进一步的十六进制代码。为特定处理器指定的指令集备忘单将揭示这一点。例如,如果您采用最简单的微处理器 8085 并且 ADD X 指令不会显示第二个值(假设 Y 像 ADD X,Y)。相反,它会将值 X 添加到处理器中的某个保留寄存器中,例如 H 并将该值存储在 H 中。如果存在溢出位,则溢出位将存储在另一个寄存器中。这就是 ADD 指令的设计方式。 CALL 指令也会有类似的预定义规则
      • 调用指令的部分工作是将返回地址压入堆栈。返回地址就是调用指令参数之后的地址。要查看上面示例中的返回地址是什么,您必须在程序进入 0x4012d0 处的过程后立即查看堆栈。
      • @Mask,你可以认为返回地址是作为存储在IP/EIP寄存器中的调用指令的地址传递的。当处理器获得下一条指令并且它是调用指令(远/短等)时,它可以将指令的大小添加到 IP 并将其推送到堆栈(SP 寄存器),这样做会将 IP 的值更改为通过 CALL 指令传递的适当地址引用(相对简称,绝对远,基于寄存器等)。附言这个问题是否仍然没有批准的答案?..
      【解决方案3】:

      这取决于 ABI 和架构,但如果返回地址确实最终在堆栈中,那是将其放在那里的 call 指令的副作用。

      【讨论】:

        【解决方案4】:

        call 将 RIP 寄存器的当前值(返回地址)推入堆栈 + 是否调用
        ret 弹出返回地址(即 调用 push)从栈顶(RSP 寄存器指向那里)并将其写入 RIP 寄存器。

        GNU/Linux 机器上的示例:函数 f 调用函数 g 并查看 g 的框架。

        低地址

        ... g 的本地变量
        f 的基指针(旧 RBP 值) f 的 ret 地址(旧 RIP 值)(这是 call(来自 f)推送的内容,以及 ret(来自 g)将弹出的内容)
        f 调用 g 并且不适合寄存器的参数(我认为在 Windows 上这是不同的)
        ...

        高地址

        g 将释放本地变量 (movq %rsp, %rbp)
        g 将弹出“旧 RBP”并将其存储在 RBP 寄存器中 (pop %rbp)
        g 将ret,它将使用存储在 RSP 指向的位置的值修改 RIP

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2010-12-14
          • 2021-05-20
          • 2014-04-21
          • 1970-01-01
          • 1970-01-01
          • 2015-04-08
          • 2020-11-18
          • 2020-09-23
          相关资源
          最近更新 更多