本文将解决以下问题
局部变量是怎么创建的?
为什么局部变量的值是随机值?
函数是怎么传参的?传参的顺序是怎样的?
形参和实参是什么关系?
函数调用是怎么做的?
函数调用是结束后怎么返回的?
本文使用VS2013查看 ,从汇编语言来理解
1.基本概念
寄存器作用:寄存数据
eax:累加器 ebx:作为指针指向数据 ecx:循环计数器 edx:eax的扩展
地址寄存器:ebp,esp(维护函数栈帧)
注意:每一个函数的调用,都会在栈区创造一个空间
画图解释
cpp
#include <stdio.h>
int add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = add(a, b);
printf("%d\n",c);
getchar();
return 0;
}
2.main函数的调用
按F11后点击调用堆栈
执行完后:
cpp
//crtexe.c的代码
#endif /* _WINMAIN_ */
void
)
{
/*
* The /GS security cookie must be initialized before any exception
* handling targetting the current image is registered. No function
* using exception handling can be called in the current image until
* after __security_init_cookie has been called.
*/
__security_init_cookie();
return __tmainCRTStartup();
}
........................
static
int
__tmainCRTStartup(
void
);
........................
#else /* WPRFLAG */
__initenv = envp;
mainret = main(argc, argv, envp);//main函数被调用
则调用关系为mainCRTStartup-->__tmainCRTStartup-->main
3.从反汇编上理解
按F11后右击反汇编,选择不显示符号名
cpp
#include <stdio.h>
int add(int x, int y)
{
000213C0 push ebp
000213C1 mov ebp,esp
000213C3 sub esp,0CCh
000213C9 push ebx
000213CA push esi
000213CB push edi
000213CC lea edi,[ebp+FFFFFF34h]
000213D2 mov ecx,33h
000213D7 mov eax,0CCCCCCCCh
000213DC rep stos dword ptr es:[edi]
int z = 0;
000213DE mov dword ptr [ebp-8],0
z = x + y;
000213E5 mov eax,dword ptr [ebp+8]
000213E8 add eax,dword ptr [ebp+0Ch]
000213EB mov dword ptr [ebp-8],eax
return z;
000213EE mov eax,dword ptr [ebp-8]
}
000213F1 pop edi
000213F2 pop esi
000213F3 pop ebx
000213F4 mov esp,ebp
000213F6 pop ebp
000213F7 ret
--------------------------------------------------------------------
int main()
{
00021410 push ebp
00021411 mov ebp,esp
00021413 sub esp,0E4h
00021419 push ebx
0002141A push esi
0002141B push edi
0002141C lea edi,[ebp+FFFFFF1Ch]
00021422 mov ecx,39h
00021427 mov eax,0CCCCCCCCh
0002142C rep stos dword ptr es:[edi]
int a = 10;
0002142E mov dword ptr [ebp-8],0Ah
int b = 20;
00021435 mov dword ptr [ebp-14h],14h
int c = 0;
0002143C mov dword ptr [ebp-20h],0
c = add(a, b);
00021443 mov eax,dword ptr [ebp-14h]
00021446 push eax
00021447 mov ecx,dword ptr [ebp-8]
0002144A push ecx
0002144B call 000210E6
00021450 add esp,8
00021453 mov dword ptr [ebp-20h],eax
printf("%d\n",c);
00021456 mov esi,esp
00021458 mov eax,dword ptr [ebp-20h]
0002145B push eax
0002145C push 25858h
00021461 call dword ptr ds:[00029114h]
00021467 add esp,8
0002146A cmp esi,esp
0002146C call 0002113B
return 0;
00021471 xor eax,eax
}
00021473 pop edi
00021474 pop esi
00021475 pop ebx
00021476 add esp,0E4h
0002147C cmp ebp,esp
0002147E call 0002113B
00021483 mov esp,ebp
00021485 pop ebp
00021486 ret
图片详解:
4.视频演示
36.【C语言】函数栈帧的创建和销毁文章的汇编演示
4.往期推荐