【发布时间】:2022-01-01 16:21:19
【问题描述】:
所以我在大学里有这个东西,我需要做一个简单的递归。似乎很好,我可以在 20 分钟内用 C 语言做到这一点。但是他们没有在课程中教我们关于汇编中的递归函数的课程,所以我在谷歌上查到了它。我只找到了这个 - https://scottc130.medium.com/recusive-functions-in-x86-assembly-5ba412bc7957 - 我有几个问题:
- 为什么将 ebp 推到这里?我看到了 pop ,所以对我来说将某些东西推入堆栈而不弹出它是没有意义的。
- 在解释部分,那个 eip 是什么,它在哪里被压入堆栈?
我想我可能已经稍微理解了,但我宁愿把它弄糊涂一点。
factorial:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cmpl $1, %eax
je end_factorial
decl %eax
pushl %eax
call factorial
movl 8(%ebp), %ebx
imul %ebx, %eax
end_factorial:
movl %ebp, %esp
popl %ebp
ret
【问题讨论】:
-
末尾有
pop ebp。eip为指令指针,由call自动推送。 -
请edit您的问题并将相关代码sn-ps从外部资源复制到您的帖子中,以便即使链接断开也可以理解您的问题。
-
因为每次调用都有返回,所以是平衡的。
-
您似乎认为
end_factorial:就像一个单独的函数,但事实并非如此。这只是一个标签。如果je被占用,我们会到达end_factorial并弹出;如果不是,则在imul %ebx, %eax之后到达end_factorial,并且在这种情况下也完成了pop。没有不平衡。 -
在汇编语言和其他语言中,递归的巧妙之处在于没有什么特别的事情可做。函数调用的编码完全相同,无论是对不同函数的调用还是对这个函数的递归调用。