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

2019-10-02  本文已影响0人  编程异思坊

上一篇讲解了 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 函数的返回过程。返回过程就下篇文章再讲解,敬请期待!

上一篇 下一篇

猜你喜欢

热点阅读