【发布时间】:2016-01-10 00:37:06
【问题描述】:
给定以下递归函数:
int silly(int n, int *p)
{
int val, val2;
if (n > 0) {
val2 = silly(n << 1, &val);
} else {
val = val2 = 0;
}
*p = val + val2 + n;
return val + val2;
}
如果不启用优化器,则会产生以下汇编代码:
silly:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
cmpl $0, -20(%rbp)
jle .L2
movl -20(%rbp), %eax
leal (%rax,%rax), %edx
leaq -8(%rbp), %rax
movq %rax, %rsi
movl %edx, %edi
call silly
movl %eax, -4(%rbp)
jmp .L3
.L2:
movl $0, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, -8(%rbp)
.L3:
movl -8(%rbp), %edx
movl -4(%rbp), %eax
addl %eax, %edx
movl -20(%rbp), %eax
addl %eax, %edx
movq -32(%rbp), %rax
movl %edx, (%rax)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
addl %edx, %eax
movq %rbp, %rsp
popq %rbp
ret
谁能帮我画出这个函数中使用的堆栈帧,指出程序值的存储位置和位置
%rsp 和 %rbp 寄存器在递归调用之前指向
silly() ?
【问题讨论】:
-
协助,是的,为你做,不。展示你的发现。
-
提示 1:看起来参数正在寄存器中传递。提示 2:
(%rbp)使用了 4 个唯一偏移量,并且您有 2 个 args 和 2 个局部变量。 -
在 x86/64 中,前 六个 参数在寄存器中传递 [即不在堆栈上],无论优化如何,这都是正确的。如果您仔细观察,这就是前两个参数分别来自
%edi和%rsi的原因。并且,在下图中,颠倒%rbp和return address的顺序[他们错了]。 -
这不是机器码,而是汇编代码