首页 > 代码库 > 函数调用的栈空间结构

函数调用的栈空间结构

  对函数调用过程的栈空间结构以前就知道,直到周二技术沙龙有同事提出不同看法,当时未能作答,这里分析一下。

测试代码如下:

int add(int a, int b){    int i = a + b;    return i;}int func(int a, int b){    return add(3, 5);   }int main(){    int a = func(3, 5);     return 0;}

linux下生成汇编代码如下:

add:.LFB0:    .cfi_startproc    pushl   %ebp    ;保存ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp  ;esp指向栈底    .cfi_def_cfa_register 5    subl    $16, %esp  ;预留栈空间    movl    12(%ebp), %eax    movl    8(%ebp), %edx    addl    %edx, %eax    movl    %eax, -4(%ebp)    movl    -4(%ebp), %eax    leave    ;见汇编指令解释    .cfi_restore 5    .cfi_def_cfa 4, 4    ret     ;见汇编指令解释    .cfi_endproc.LFE0:    .size   add, .-add    .globl  func    .type   func, @functionfunc:.LFB1:    .cfi_startproc    pushl   %ebp  ;ebp入栈    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp  ;esp指向栈底    .cfi_def_cfa_register 5    subl    $8, %esp    movl    $5, 4(%esp)    movl    $3, (%esp)    call    add    ;返回地址入栈,并跳转到add    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE1:    .size   func, .-func    .globl  main    .type   main, @function

几条指令的汇编解释:

call:

  push eip

  jmp

leave:

  mov esp,ebp

  pop ebp

ret:

  pop eip

  add esp,4

pop eip:

  mov eip, [esp]

  add esp,4

 

栈空间结构图示:

————————————

ebp

local variable

5            ;func栈桢

3

返回地址

————————————

ebp  ;保存func的ebp

local variable

————————————

函数调用的栈空间结构