36 C language function call stack information

foreword

There was an analysis of java method call stack information before and  the stack frame information of the main method

Here we look at the stack information of the function call in the c language. Compared with the stack information of java, it is simpler here 

Because everything in the stack information can be seen in the corresponding assembly 

However, java method calls themselves encapsulate another layer, and the cost is slightly higher 

test case


    #include "stdio.h"

    int func_3(int arg3) {
        int locals_3 = 3;
        int locals_4 = 4;
        return locals_3 + locals_4 + arg3;
    }

    int func_2(int arg2) {
        int locals_2 = 2;
        return func_3(locals_2 + arg2);
    }

    int func_1(int arg1) {
        int locals_1 = 1;
        return func_2(locals_1 + arg1);
    }

    int main(int argc, char **argv) {

        int locals_0 = 10;
        int result = func_1(locals_0);

        printf(" func_1 arg0 : %d, result : %d \n", locals_0, result);

    }

stack information

The stack information is as follows 

    (gdb) x /20gx 0x7fffffffe3d0
    0x7fffffffe3d0: 0x0000000000000000 0x0000000d00000000 // func_3_locals | arg3
    0x7fffffffe3e0: 0x0000000000000000 0x0000000400000003 // func_3_locals | local_3, locals_4
    0x7fffffffe3f0: 0x00007fffffffe418 0x000000000040056b // func_2's bp, func_2'sreturnAddress
    0x7fffffffe400: 0x0000000b00000000 0x0000000000000000 // func_2_locals | arg2
    0x7fffffffe410: 0x0000000200000000 0x00007fffffffe440 // func_2_locals, func_1's bp | locals_2
    0x7fffffffe420: 0x000000000040058e 0x0000000a00000000 // func_1's returnAddress, func_1_locals | arg1
    0x7fffffffe430: 0x0000000000000001 0x000000010040062d // func_1_locals | locals_1
    0x7fffffffe440: 0x00007fffffffe470 0x00000000004005b0 // main's bp, main'sReturnAddress
    0x7fffffffe450: 0x00007fffffffe558 0x0000000100400430 // main_locals | si, di
    0x7fffffffe460: 0x00007fffffffe550 0x000000000000000a // main_locals | locals_0
    0x7fffffffe470: 0x00000000004005e0 0x00007ffff7a2d840 // caller's bp, x
    0x7fffffffe480: 0x0000000000000000 0x00007fffffffe558

Let's list the contents of each function separately, you can look at it against the stack information above 

Here is just a simple example, if there are too many parameters, some parameters will also be placed on the stack

(gdb) disassemble main 
Dump of assembler code for function main:
   0x0000000000400590 <+0>:	push   %rbp
   0x0000000000400591 <+1>:	mov    %rsp,%rbp
   0x0000000000400594 <+4>:	sub    $0x20,%rsp
   0x0000000000400598 <+8>:	mov    %edi,-0x14(%rbp)
   0x000000000040059b <+11>:	mov    %rsi,-0x20(%rbp)
   0x000000000040059f <+15>:	movl   $0xa,-0x8(%rbp)
   0x00000000004005a6 <+22>:	mov    -0x8(%rbp),%eax
   0x00000000004005a9 <+25>:	mov    %eax,%edi
   0x00000000004005ab <+27>:	callq  0x40056d <func_1>
   0x00000000004005b0 <+32>:	mov    %eax,-0x4(%rbp)
   0x00000000004005b3 <+35>:	mov    -0x4(%rbp),%edx
   0x00000000004005b6 <+38>:	mov    -0x8(%rbp),%eax
   0x00000000004005b9 <+41>:	mov    %eax,%esi
   0x00000000004005bb <+43>:	mov    $0x400668,%edi
   0x00000000004005c0 <+48>:	mov    $0x0,%eax
   0x00000000004005c5 <+53>:	callq  0x400400 <printf@plt>
   0x00000000004005ca <+58>:	mov    $0x0,%eax
   0x00000000004005cf <+63>:	leaveq 
   0x00000000004005d0 <+64>:	retq   
End of assembler dump.
(gdb) disassemble func_1
Dump of assembler code for function func_1:
   0x000000000040056d <+0>:	push   %rbp
   0x000000000040056e <+1>:	mov    %rsp,%rbp
   0x0000000000400571 <+4>:	sub    $0x18,%rsp
   0x0000000000400575 <+8>:	mov    %edi,-0x14(%rbp)
   0x0000000000400578 <+11>:	movl   $0x1,-0x4(%rbp)
   0x000000000040057f <+18>:	mov    -0x4(%rbp),%edx
   0x0000000000400582 <+21>:	mov    -0x14(%rbp),%eax
   0x0000000000400585 <+24>:	add    %edx,%eax
   0x0000000000400587 <+26>:	mov    %eax,%edi
   0x0000000000400589 <+28>:	callq  0x40054a <func_2>
   0x000000000040058e <+33>:	leaveq 
   0x000000000040058f <+34>:	retq   
End of assembler dump.
(gdb) disassemble func_2
Dump of assembler code for function func_2:
   0x000000000040054a <+0>:	push   %rbp
   0x000000000040054b <+1>:	mov    %rsp,%rbp
   0x000000000040054e <+4>:	sub    $0x18,%rsp
   0x0000000000400552 <+8>:	mov    %edi,-0x14(%rbp)
   0x0000000000400555 <+11>:	movl   $0x2,-0x4(%rbp)
   0x000000000040055c <+18>:	mov    -0x4(%rbp),%edx
   0x000000000040055f <+21>:	mov    -0x14(%rbp),%eax
   0x0000000000400562 <+24>:	add    %edx,%eax
   0x0000000000400564 <+26>:	mov    %eax,%edi
   0x0000000000400566 <+28>:	callq  0x400526 <func_3>
   0x000000000040056b <+33>:	leaveq 
   0x000000000040056c <+34>:	retq   
End of assembler dump.
(gdb) disassemble func_3
Dump of assembler code for function func_3:
   0x0000000000400526 <+0>:	push   %rbp
   0x0000000000400527 <+1>:	mov    %rsp,%rbp
   0x000000000040052a <+4>:	mov    %edi,-0x14(%rbp)
   0x000000000040052d <+7>:	movl   $0x3,-0x8(%rbp)
   0x0000000000400534 <+14>:	movl   $0x4,-0x4(%rbp)
   0x000000000040053b <+21>:	mov    -0x8(%rbp),%edx
   0x000000000040053e <+24>:	mov    -0x4(%rbp),%eax
   0x0000000000400541 <+27>:	add    %eax,%edx
   0x0000000000400543 <+29>:	mov    -0x14(%rbp),%eax
=> 0x0000000000400546 <+32>:	add    %edx,%eax
   0x0000000000400548 <+34>:	pop    %rbp
   0x0000000000400549 <+35>:	retq   

over 

Guess you like

Origin blog.csdn.net/u011039332/article/details/128305693