【问题标题】:Retq instruction, where does it returnRetq指令,它在哪里返回
【发布时间】:2026-02-05 21:10:01
【问题描述】:

我无法理解汇编指令retq 返回到哪里。

我了解当我的正常代码执行时,它会返回到堆栈中指定的地址。但是它怎么知道返回地址在栈中的哪个位置呢?

简而言之,它是使用 rbp 还是 esp 来查找堆栈上的地址?

【问题讨论】:

  • 如果您想进行实验,请尝试将retq 替换为addq $8, %rsp; jmpq -8(%rsp)。功能上等价(虽然不是性能方面)。

标签: assembly x86-64 stack-overflow inline-assembly


【解决方案1】:

在学习了汇编代码之后,这是我的想法, 让我们看一个示例:

fun:
push %rbp
mov %rsp,%rbp
...
...
pop %rbp
retq

main:
...
...
callq  "address" <fun>
...
...

我们可以看到retq之前有一条指令。 pop %rbp(有时是离开指令,但它们相似)指令将

  1. 将当前堆栈指针%rsp的内容保存到基堆栈指针%rbp
  2. %rsp 指针移动到堆栈上的前一个地址。

例如:在 pop 命令之前,%rsp 指向了0x0000 0000 0000 00D0。在pop 命令之后,它指向0x0000 0000 0000 00D8(假设堆栈从高地址增长到低地址)。

pop 命令之后,现在%rsp 指向一个新地址,retq 将此地址作为返回地址。

【讨论】:

    【解决方案2】:

    ret 是您在 x86 上拼写 pop rip 的方式:堆栈弹出和指向该值的间接分支。 https://www.felixcloutier.com/x86/ret 准确记录了它做什么和不做什么。

    实际上是pop %tmp / jmp *%tmp,其中tmp 是一个内部临时寄存器。

    ret 仅依赖于 RSP。

    将 RBP 用作帧指针是一种完全可选的软件约定,现代编译器甚至在启用优化时都不会这样做。

    【讨论】: