那些年“错过”的C函数调用原理(二)

上一篇讲解了 C 函数调用原理的一些基本概念,如果还没有完全理解可以回过头多看两遍。技术知识总需要反反复复回过头理解,每一次反复都能得到新的理解。

关于栈帧的建立和删除,下面用一个简单 C 程序实例来进行说明。

int add(int a,int b)
{ 
    int result=a+b; 
    return result; 
} 

int main(int argc) 
{ 
    int answer;
    answer=add(40,2);
    return 0;
}

时刻保持持续学习的状态,每天会过得越来越充实。能坚持看到这里的读者朋友已经非常不容易了,每天多进步一点点,差距就会慢慢拉开的,加油!

言归正传,要了解 C 函数内部调用原理是离不开汇编代码的,下面列举了一些基础汇编代码,加上注释和配图就比较好理解其调用过程。

注:汇编代码框能够左右滑动,可左滑查看被隐藏部分

call main  #push return address into stack,jump into main
push %ebp  #save current ebp register value
mov %esp,%ebp  #copy esp to ebp
sub $12,%esp  #make room for stack data

步骤 1 到 4 是调用 main 函数时建立栈帧的过程:

image

main 函数调用过程是通用的,基本上每个函数都要执行这个调用过程。调用过程可以简单理解为:如步骤 2 到步骤 4 所示,ebp 的当前值被保存到了栈的顶部,然后,将 esp 的内容拷贝到 ebp,esp 再指向新的栈顶,以建立一个新的栈帧。

mov $2,4(%esp)  #set b to 22mov $40,(%esp) #set a to 40
call add  #push return address into stack,jump into add
push %ebp  #save current ebp register valve
mov %esp,%ebp  #copy esp to ebp
sub $4,%esp  #make room for result
mov 12(%ebp),%eax  #move b to eax
mov 8(%ebp),%edx   #move a to edx
add %edx,%eax      #add edx into eax,total is 42
mov %eax,-4(%ebp)  #copy eax to result

如步骤 11 所示,主调函数(main 函数)栈帧范围从 argc 到 answer,而被调函数(add 函数)栈帧范围从 b 到 result。至此,add 函数的调用过程结束,紧接着是 C 函数的返回过程。返回过程就下篇文章再讲解,敬请期待!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...
    小猪啊呜阅读 10,170评论 1 19
  • 首先寄存器使用惯例:eip :指令地址寄存器,保存程序计数器的值,当前执行的指令的下一条指令的地址值,16位中为i...
    扎Zn了老Fe阅读 6,046评论 0 0
  • 在 C/C++ 函数调用的整个过程中内存空间进行了什么操作?本文对 C/C++ 函数调用原理进行扼要说明。 一、预...
    HubbardHuang阅读 12,489评论 0 9
  • 栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函...
    zjfclimin阅读 9,565评论 0 5
  • 说起电影,相信谁都不陌生。现代电影院漫天飞舞的海报,网络上营销热销预订。电影院装修的富丽堂皇,犹如宫殿一般,空调吹...
    铭帅之念阅读 5,780评论 28 16