提问1.main()函数调用一个自定义函数之后(函数的定义再main()外),如何再次回到main()的位置;
提问2.既然知道返回main()函数,那如何知道返回到main()函数的哪一行操作呢?
我们先写一段代码,方便研究:
int sum(int a,int b)
{
int temp=a+b;
return temp;
}
int main()
{
int x = 10;
int y = 20;
int result = sum(x,y);
cout<<result<<endl;
return 0;
}
记得上节课我们有一个重要的总结,所有的代码到计算机层面呢就是指令和数据;同时,我们在分析的时候就需要有些汇编的基础。
首先说明压栈和出栈;
栈是一种特殊的数据结构,符合先进后出的特性,压栈操作呢使得栈增大,而出栈操作使得栈变小;每个栈呢都有ebp、esp寄存器定位,其中esp永远指向栈顶位置,这时候呢压栈就会造成esp地址减小,出栈就造成esp地址增大(栈是个奇葩,地址是反着来的);
画个图解释一下吧:
打个断点,转到反汇编语言,
整个操作的汇编代码如下:
int sum(int a, int b)
{
00D31890 push ebp
00D31891 mov ebp,esp
00D31893 sub esp,0CCh
00D31899 push ebx
00D3189A push esi
00D3189B push edi
00D3189C lea edi,[ebp-0CCh]
00D318A2 mov ecx,33h
00D318A7 mov eax,0CCCCCCCCh
00D318AC rep stos dword ptr es:[edi]
00D318AE mov ecx,offset _7F4A7534_源@cpp (0D3C027h)
00D318B3 call @__CheckForDebuggerJustMyCode@4 (0D31226h)
int temp = a + b;
00D318B8 mov eax,dword ptr [a]
00D318BB add eax,dword ptr [b]
00D318BE mov dword ptr [temp],eax
return temp;
00D318C1 mov eax,dword ptr [temp]
}
int main()
{
00D31900 push ebp
00D31901 mov ebp,esp
00D31903 sub esp,0E4h
00D31909 push ebx
00D3190A push esi
00D3190B push edi
00D3190C lea edi,[ebp-0E4h]
00D31912 mov ecx,39h
00D31917 mov eax,0CCCCCCCCh
00D3191C rep stos dword ptr es:[edi]
00D3191E mov ecx,offset _7F4A7534_源@cpp (0D3C027h)
00D31923 call @__CheckForDebuggerJustMyCode@4 (0D31226h)
int x = 10;
00D31928 mov dword ptr [x],0Ah
int y = 20;
00D3192F mov dword ptr [y],14h
int result = sum(x, y);
00D31936 mov eax,dword ptr [y]
00D31939 push eax
00D3193A mov ecx,dword ptr [x]
00D3193D push ecx
00D3193E call sum (0D31087h)
00D31943 add esp,8
00D31946 mov dword ptr [result],eax
cout << result << endl;
00D31949 mov esi,esp
00D3194B push offset std::endl<char,std::char_traits<char> > (0D31253h)
00D31950 mov edi,esp
00D31952 mov eax,dword ptr [result]
00D31955 push eax
00D31956 mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (0D3B0A8h)]
00D3195C call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0D3B09Ch)]
00D31962 cmp edi,esp
00D31964 call __RTC_CheckEsp (0D31230h)
00D31969 mov ecx,eax
00D3196B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0D3B0A0h)]
00D31971 cmp esi,esp
00D31973 call __RTC_CheckEsp (0D31230h)
return 0;
00D31978 xor eax,eax
}
1.将main()函数的mainCTRstartup函数的栈底指针压栈,并且初始化main()的栈帧空间;
2.当运行到sum()函数时,esp和ebp会移动到栈顶新开辟出的地址,用于完
成sum()函数的操作;
3.在sum()函数计算过程中,借助寄存器eax完成,根据汇编语言可以看出将a,b的值放入到了寄存器eax中;
4.之后会回退sum()函数的栈空间,出栈、并且回退到main()函数的栈底;