如果在没有调用的情况下使用 ret 会发生什么?
What happens if ret is used without a call?
我对汇编还很陌生,我想知道 ret 的行为。如果我在代码中从不使用调用,而是在末尾放一个 ret,代码就会回到开头。这是没有调用时的默认行为吗?如果我使用 jmp,如果仍然没有调用,那会影响 ret 的行为吗?
call
将下一条指令的地址放入调用栈,然后跳转到目标地址。
ret
从调用堆栈弹出最后一个地址,然后跳转到这里。好像如果栈是空的,就returns0x00000000
,然后跳转到程序开头。 至少在某些系统中。由于地址 space 违规,您不应该使用它。
jmp
对调用堆栈 没有影响 ,因此它不会修改 ret
.
的行为
编辑:如@PeterCordes 所写;如果您使用 push
或 pop
,它们可以写入堆栈内存,而 ret
会弹出它。
在许多系统中,bootup/startup 代码实际上 调用 main()
函数(或其等效函数),例如使用 https://www.nongnu.org/avr-libc/ 的裸机 AVR 程序(其优点是编译器可以将 main()
编译为任何其他函数,不需要任何特殊处理)。
因此,当您在 main()
中的用户代码执行 ret
(即使您的用户代码本身从未实际调用 anthing)时,您的用户代码将从该隐式调用中 return 并且bootup/startup 代码将继续 运行。
现在的问题是 bootup/startup 代码在 main()
已经 return 之后做了什么。它可能会进入无休止的忙碌循环、停止系统、关闭电源、重新启动等。
我对汇编还很陌生,我想知道 ret 的行为。如果我在代码中从不使用调用,而是在末尾放一个 ret,代码就会回到开头。这是没有调用时的默认行为吗?如果我使用 jmp,如果仍然没有调用,那会影响 ret 的行为吗?
call
将下一条指令的地址放入调用栈,然后跳转到目标地址。
ret
从调用堆栈弹出最后一个地址,然后跳转到这里。好像如果栈是空的,就returns0x00000000
,然后跳转到程序开头。 至少在某些系统中。由于地址 space 违规,您不应该使用它。
jmp
对调用堆栈 没有影响 ,因此它不会修改 ret
.
编辑:如@PeterCordes 所写;如果您使用 push
或 pop
,它们可以写入堆栈内存,而 ret
会弹出它。
在许多系统中,bootup/startup 代码实际上 调用 main()
函数(或其等效函数),例如使用 https://www.nongnu.org/avr-libc/ 的裸机 AVR 程序(其优点是编译器可以将 main()
编译为任何其他函数,不需要任何特殊处理)。
因此,当您在 main()
中的用户代码执行 ret
(即使您的用户代码本身从未实际调用 anthing)时,您的用户代码将从该隐式调用中 return 并且bootup/startup 代码将继续 运行。
现在的问题是 bootup/startup 代码在 main()
已经 return 之后做了什么。它可能会进入无休止的忙碌循环、停止系统、关闭电源、重新启动等。