【发布时间】:2015-12-15 02:33:14
【问题描述】:
这是 AT&T 语法
.global bar
.type bar, @function
bar:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
movl 8($ebp), %ebx
movl $1, %eax
cmpl $1, %ebx
jle .L3
leal -1(%ebx), %eax //subtracts 1 from ebx and stores into eax
movl %eax, (%esp) //putting on stack frame
call bar //recursive call
addl %ebx, %eax // adds %ebx and %eax
.L3 //returns %eax
addl $20, %esp
popl %ebx
popl %ebp
ret //end of bar
所以我认为这里发生的基本上是它检查 %ebx 是否
所以我的 C 代码是:
int bar (int x)
{
if (x<= 1)
return 1;
else
return x + bar(x-1);
}
递归调用真的把我骗到这里了。我意识到它使用新的 %eax 寄存器(基本上变成 x-1)调用 bar 。那么它只是返回数字的总和吗?
【问题讨论】:
-
我看不到你在哪里得到
x+(x-1)的递归调用参数。有一个addafter 通话,您似乎与通话before 发生的事情混为一谈。leal -1(%ebx),%eax是加载有效地址指令。它记录在 x86 手册中(很多是在线的)。它用于存储带有偏移量的地址,但有时它用于通过一次执行移动和常量添加来保存一条指令。我没有看到 将eax添加到堆栈 的位置。您必须将其移动到堆栈,这是将其作为arg传递给bar的必要条件。 -
@lurker 我意识到我搞砸了它的递归调用,我正在努力追溯它。 leal 命令是从 ebx 中减去 1 并将其存储到 eax 中,尽管正确吗?
-
是的,没错。
-
@lurker 我重新查看了它并再次尝试了解决方案。我认为它实际上只是将 x 到 1 的值相加。