如果在没有调用的情况下使用 ret 会发生什么?

What happens if ret is used without a call?

我对汇编还很陌生,我想知道 ret 的行为。如果我在代码中从不使用调用,而是在末尾放一个 ret,代码就会回到开头。这是没有调用时的默认行为吗?如果我使用 jmp,如果仍然没有调用,那会影响 ret 的行为吗?

call将下一条指令的地址放入调用栈,然后跳转到目标地址。

ret 从调用堆栈弹出最后一个地址,然后跳转到这里。好像如果栈是空的,就returns0x00000000,然后跳转到程序开头。 至少在某些系统中。由于地址 space 违规,您不应该使用它。

jmp 对调用堆栈 没有影响 ,因此它不会修改 ret.

的行为

编辑:如@PeterCordes 所写;如果您使用 pushpop,它们可以写入堆栈内存,而 ret 会弹出它。

在许多系统中,bootup/startup 代码实际上 调用 main() 函数(或其等效函数),例如使用 https://www.nongnu.org/avr-libc/ 的裸机 AVR 程序(其优点是编译器可以将 main() 编译为任何其他函数,不需要任何特殊处理)。

因此,当您在 main() 中的用户代码执行 ret(即使您的用户代码本身从未实际调用 anthing)时,您的用户代码将从该隐式调用中 return 并且bootup/startup 代码将继续 运行。

现在的问题是 bootup/startup 代码在 main() 已经 return 之后做了什么。它可能会进入无休止的忙碌循环、停止系统、关闭电源、重新启动等。