Assembly Retq指令,它在哪里返回

Assembly Retq指令,它在哪里返回,assembly,x86-64,stack-overflow,inline-assembly,Assembly,X86 64,Stack Overflow,Inline Assembly,我无法理解汇编指令retq返回到哪里 我知道当我的普通代码执行时,它会返回到堆栈中指定的地址。但它如何知道返回地址在堆栈中的位置呢 简而言之,它是使用rbp还是esp在堆栈上查找地址?在研究汇编代码之后,下面是我的想法, 让我们看一个示例: fun: push %rbp mov %rsp,%rbp ... ... pop %rbp retq main: ... ... callq "address" <fun> ... ... 乐趣: 推送%rbp mov%rsp,%rbp .

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

我知道当我的普通代码执行时,它会返回到堆栈中指定的地址。但它如何知道返回地址在堆栈中的位置呢


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

在研究汇编代码之后,下面是我的想法, 让我们看一个示例:

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

main:
...
...
callq  "address" <fun>
...
...
乐趣:
推送%rbp
mov%rsp,%rbp
...
...
弹出%rbp
retq
主要内容:
...
...
callq“地址”
...
...
我们可以看到在
retq
之前有一条指令。
pop%rbp
(有时是请假指令,但它们类似)指令将

  • 将当前堆栈指针
    %rsp
    的内容保存到基本堆栈指针
    %rbp
  • %rsp
    指针移动到堆栈上的上一个地址 例如:在pop命令之前,
    %rsp
    指向
    0x0000 00D0
    。在
    pop
    命令之后,它指向
    0x0000 00D8
    (假设堆栈从高地址增长到低地址)


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

    ret
    是x86上拼写
    pop-rip
    的方式:堆栈pop和该值的间接分支。准确记录它做什么和不做什么

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

    ret
    仅取决于RSP


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

    如果您想进行实验,请尝试将
    retq
    替换为
    addq$8,%rsp;jmpq-8(%rsp)
    。功能上等效(但性能上不等效)。