Why 'rbp' of a frame is not matching 'rsp' of previous frame?

85 Views Asked by At
#include <stdio.h>

int
funcB(int *ret)
{
    int x = 10;
    x += *ret;;
    printf("%d\n", x);
    return 0;
}

int
funcA(int x, int y)
{
    int ret = 0;
    ret = x + y;
    funcB(&ret);
    ret += 10;
    return ret;
}

int
main(void)
{
    int ret;
    ret = funcA(10, 20);
    printf("%d\n", ret);
    return 0;
}

As per the assembly instruction, I was expecting that 'rbp' of funcB() will be the same as 'rsp' of funcA(). But that is not the case. Looks like 'rbp' of funcB is changed somewhere? Why is it so?

(gdb) b main
Breakpoint 1 at 0x4005a6: file tmp.c, line 26.
(gdb) b funcA
Breakpoint 2 at 0x400572: file tmp.c, line 15.
(gdb) b funcB
Breakpoint 3 at 0x400539: file tmp.c, line 6.
(gdb) run
Starting program: /nobackup/ibhattac/code/./a.out

Breakpoint 1, main () at tmp.c:26
26          ret = funcA(10, 20);
(gdb) info reg rsp
rsp            0x7fffffffdd00   0x7fffffffdd00
(gdb) info reg rbp
rbp            0x7fffffffdd10   0x7fffffffdd10
(gdb) c
Continuing.

Breakpoint 2, funcA (x=10, y=20) at tmp.c:15
15          int ret = 0;
(gdb) info reg rsp
rsp            0x7fffffffdcd0   0x7fffffffdcd0
(gdb) info reg rbp
rbp            0x7fffffffdcf0   0x7fffffffdcf0
(gdb) c
Continuing.

Breakpoint 3, funcB (ret=0x7fffffffdcec) at tmp.c:6
6           int x = 10;
(gdb) info reg rsp
rsp            0x7fffffffdca0   0x7fffffffdca0
(gdb) info reg rbp
rbp            0x7fffffffdcc0   0x7fffffffdcc0  >>> Why this is not same as 'rsp' of funcA()

Does 'rsp' of funcA() change to make space for push %rbp and the return instruction counter?

Does that mean leaveq in funcB() modifies rbp and only then load it to rsp?

(gdb) disassemble funcB
Dump of assembler code for function funcB:
   0x000000000040052d <+0>:     push   %rbp   
   0x000000000040052e <+1>:     mov    %rsp,%rbp
   0x0000000000400531 <+4>:     sub    $0x20,%rsp
   0x0000000000400535 <+8>:     mov    %rdi,-0x18(%rbp)
   0x0000000000400539 <+12>:    movl   $0xa,-0x4(%rbp)
   0x0000000000400540 <+19>:    mov    -0x18(%rbp),%rax
   0x0000000000400544 <+23>:    mov    (%rax),%eax
   0x0000000000400546 <+25>:    add    %eax,-0x4(%rbp)
=> 0x0000000000400549 <+28>:    mov    -0x4(%rbp),%eax
   0x000000000040054c <+31>:    mov    %eax,%esi
   0x000000000040054e <+33>:    mov    $0x400670,%edi
   0x0000000000400553 <+38>:    mov    $0x0,%eax
   0x0000000000400558 <+43>:    callq  0x400410 <printf@plt>
   0x000000000040055d <+48>:    mov    $0x0,%eax
   0x0000000000400562 <+53>:    leaveq
   0x0000000000400563 <+54>:    retq
End of assembler dump.
0

There are 0 best solutions below