【问题标题】:drawing a stack frame for recursive function为递归函数绘制堆栈帧
【发布时间】: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 的原因。并且,在下图中,颠倒%rbpreturn address 的顺序[他们错了]。
  • 这不是机器码,而是汇编代码

标签: c assembly stack


【解决方案1】:

所以这是最终的答案:

    |                                |  
    +--------------------------------+
    |                                |  
    +--------------------------------+
    |             ...                |  
    +--------------------------------+
    |        return address          |  12
    +--------------------------------+
    |        return address          |  8
    +--------------------------------+
    |             %rbp               |  4
    +--------------------------------+
    |             %rbp               |  0
    +--------------------------------+
    |             val2               |  -4
    +--------------------------------+
    |             val                |  -8
    +--------------------------------+
    |                                |  -12
    +--------------------------------+
    |                                |  -16
    +--------------------------------+
    |              n                 |  -20
    +--------------------------------+
    |                                |  -24
    +--------------------------------+
    |              p                 |  -28
    +--------------------------------+
    |              p                 |  -32
    +--------------------------------+

【讨论】:

    猜你喜欢
    • 2018-09-24
    • 2023-03-27
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 2015-08-17
    • 2017-10-20
    • 2015-04-14
    相关资源
    最近更新 更多