寄存器%rbx如何在递归调用中保留先前的值

时间:2017-08-08 02:20:00

标签: recursion assembly

C和汇编代码:

long pcount_r(unsigned long x) {
    if (x == 0) return 0;
    else return (x & 1) + pcount_r (x>>1);
}

pcoutn_r:
    movl  $0,   %eax
    testq %rdi, %rdi
    je .L6
    pushq %rbx
    movq  %rdi, %rbx
    andl  $1,   %ebx
    shrq  %rdi
    call  pcount_r
    addq  %rbx, %rax
    popq  %rbx 
.L6:
    rep; ret

如果传递函数值x = 5(二进制表示为0101)。寄存器%rdi是x值,%rbx在传递“x>> 1”之前将x值保持为“movq%rdi,%rbx”到下一个递归调用。因此,%rbx保持0101,然后是010,然后是01。

The first call of pcount_r:
%rdi        %rbx
0101  -->   0101 

The second call of pcount_r:
%rdi        %rbx
010   -->   010 

The third call and etc...

%rbx当时只能保存一个值,对我来说,它似乎只是覆盖了%rbx的先前值,而不是在堆栈上保存数据。我的问题是:当递归调用结束时,%​​rbx如何恢复之前的%rbx值?

有关此功能的更多详细信息,请参见此链接。 Recursive Procedures at time 55:00

1 个答案:

答案 0 :(得分:0)

我明白了。我的错误是我认为寄存器%rbx持有x值。但实际上,%rbx只是暂时保持x值,汇编代码“pushq%rbx”将%rbx值推送到堆栈,然后将下一个%rdi传递给%rbx。同样,该值由“popq%rbx”恢复。