在C语言的代码编写中,程序的主体是函数,就会涉及函数调用的问题。因此这里讲讲“函数调用”的过程。
以如下求两个整数的最大值的代码为例:
int max(int a,int b)
{
int max = 0;
if(a>b)
{
max = a;
}
else
{
max = b;
}
return max;
}
int main()
{
int x = 0;
int y = 0;
printf("输入两个整数:\n");
scanf("%d %d",&x,&y);
printf("%d \n",max(x,y));
return 0;
}
我们来看看程序运行的过程是怎样的,首先进行调试:

发现主函数是在__tmainCRTStartup 函数中调用的,而 __tmainCRTStartup 函数是在 mainCRTStartup 被调用的。这个过程就是函数调用的一个过程。
具体看看过程是怎样的,转到反汇编:
int max(int a,int b)
{
00D014C0 push ebp
00D014C1 mov ebp,esp
00D014C3 sub esp,0CCh
00D014C9 push ebx
00D014CA push esi
00D014CB push edi
00D014CC lea edi,[ebp-0CCh]
00D014D2 mov ecx,33h
00D014D7 mov eax,0CCCCCCCCh
00D014DC rep stos dword ptr es:[edi]
int max = 0
00D014DE mov dword ptr [max],0
if(a>b)
00D014E5 mov eax,dword ptr [a]
00D014E8 cmp eax,dword ptr [b]
00D014EB jle max+35h (0D014F5h)
{
max = a
00D014ED mov eax,dword ptr [a]
00D014F0 mov dword ptr [max],eax
}
else
00D014F3 jmp max+3Bh (0D014FBh)
{
max = b
00D014F5 mov eax,dword ptr [b]
00D014F8 mov dword ptr [max],eax
}
return max
00D014FB mov eax,dword ptr [max]
}
00D014FE pop edi
00D014FF pop esi
00D01500 pop ebx
00D01501 mov esp,ebp
00D01503 pop ebp
00D01504 ret
来一边画图一边描述:

从main函数的地方开始,要对main函数调用就要先对main函数创建栈桢,调用max函数就要先对max函数创建栈桢。
在主函数运行中,遇到max函数时,调用max函数,首先对其创建栈桢,具体过程如图:

在调用max函数时,变量max的返回值出栈带回主函数的堆栈中,将出栈的内容作为地址返回,将程序执行跳转到该地址处。
如下图所示:

这样,就完成了整个函数调用的过程,但注意,ebp始终存放的是栈底的地址,esp始终存放栈顶的地址!