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