您的位置:首页 > 编程语言 > C语言/C++

函数的调用过程、栈帧的创建以及销毁

2017-11-06 23:16 513 查看
函数的调用过程、栈帧的创建、销毁

以下面的程序为例:

#include<iostream>
using namespace std;
int sub(int a, int b)
{
int c = 0;
c = a - b;
return c;
}
int main()
{
int a1 = 3;
int b1 = 1;
int c1=sub(a1, b1);
cout << c1 << endl;
system("pause");
return 0;
}


下面为sub函数的反汇编:
17: int sub(int a, int b)
18: {
001E5230 55                   push        ebp
001E5231 8B EC                mov         ebp,esp
001E5233 81 EC CC 00 00 00    sub         esp,0CCh
001E5239 53                   push        ebx
001E523A 56                   push        esi
001E523B 57                   push        edi
001E523C 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]
001E5242 B9 33 00 00 00       mov         ecx,33h
001E5247 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
001E524C F3 AB                rep stos    dword ptr es:[edi]
19:     int c = 0;
001E524E C7 45 F8 00 00 00 00 mov         dword ptr [c],0
20:     c = a - b;
001E5255 8B 45 08             mov         eax,dword ptr [a]
001E5258 2B 45 0C             sub         eax,dword ptr [b]
001E525B 89 45 F8             mov         dword ptr [c],eax
21:     return c;
001E525E 8B 45 F8             mov         eax,dword ptr [c]
22: }


23: int main()
24: {
001E53C0 55                   push        ebp
001E53C1 8B EC                mov         ebp,esp
001E53C3 81 EC E4 00 00 00    sub         esp,0E4h
001E53C9 53                   push        ebx
001E53CA 56                   push        esi
001E53CB 57                   push        edi
001E53CC 8D BD 1C FF FF FF    lea         edi,[ebp-0E4h]
001E53D2 B9 39 00 00 00       mov         ecx,39h
001E53D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
001E53DC F3 AB                rep stos    dword ptr es:[edi]
25:     int a1 = 3;
001E53DE C7 45 F8 03 00 00 00 mov         dword ptr [a1],3
26:     int b1 = 1;
001E53E5 C7 45 EC 01 00 00 00 mov         dword ptr [b1],1
27:     int c1=sub(a1, b1);
001E53EC 8B 45 EC             mov         eax,dword ptr [b1]
001E53EF 50                   push        eax
001E53F0 8B 4D F8             mov         ecx,dword ptr [a1]
001E53F3 51                   push        ecx
001E53F4 E8 77 BF FF FF       call        sub (01E1370h)
001E53F9 83 C4 08             add         esp,8
001E53FC 89 45 E0             mov         dword ptr [c1],eax
28:     cout << c1 << endl;
001E53FF 8B F4                mov         esi,esp
001E5401 68 9D 13 1E 00       push        1E139Dh
001E5406 8B FC                mov         edi,esp
001E5408 8B 45 E0             mov         eax,dword ptr [c1]
001E540B 50                   <
4000
span class="hljs-keyword">push        eax
001E540C 8B 0D 90 00 1F 00    mov         ecx,dword ptr ds:[1F0090h]
001E5412 FF 15 9C 00 1F 00    call        dword ptr ds:[1F009Ch]
001E5418 3B FC                cmp         edi,esp
001E541A E8 CF BE FF FF       call        __RTC_CheckEsp (01E12EEh)
001E541F 8B C8                mov         ecx,eax
001E5421 FF 15 A0 00 1F 00    call        dword ptr ds:[1F00A0h]
001E5427 3B F4                cmp         esi,esp
001E5429 E8 C0 BE FF FF       call        __RTC_CheckEsp (01E12EEh)
29:     system("pause");
001E542E 8B F4                mov         esi,esp
001E5430 68 70 CC 1E 00       push        1ECC70h
29:     system("pause");
001E5435 FF 15 9C 01 1F 00    call        dword ptr ds:[1F019Ch]
001E543B 83 C4 04             add         esp,4
001E543E 3B F4                cmp         esi,esp
001E5440 E8 A9 BE FF FF       call        __RTC_CheckEsp (01E12EEh)
30:     return 0;
001E5445 33 C0                xor         eax,eax
31: }


001E53C0 55 push ebp 此句反汇编描述如下:







001E53C9 53                   push        ebx
001E53CA 56                   push        esi
001E53CB 57                   push        edi


这三行操作为压栈操作,起到保护空间的作用:



001E53CC 8D BD 1C FF FF FF    lea         edi,[ebp-0E4h]  //将main函数的空间地址加载给edi
001E53D2 B9 39 00 00 00       mov         ecx,39h  //将39h给ecx
001E53D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh //将0CCCCCCCCh 给eax
001E53DC F3 AB                rep stos    dword ptr es:[edi]//重复操作。


相当于main函数空间的初始化。



下面来看看内存块:



此段反汇编为调用sub函数的汇编代码:
27:   int c1=sub(a1, b1);
001E53EC 8B 45 EC             mov         eax,dword ptr [b1]//将b1的值给eax
001E53EF 50                   push        eax  //将eax压入栈内
001E53F0 8B 4D F8             mov         ecx,dword ptr [a1] //将a1的值给ecx
001E53F3 51                   push        ecx //将ecx压到栈内
001E53F4 E8 77 BF FF FF       call        sub (01E1370h)  //call指令、调用sub函数
001E53F9 83 C4 08             add         esp,8
001E53FC 89 45 E0             mov         dword ptr [c1],eax //将




之后进行sub函数的分析:



这段为出栈过程,将空间还回。
001E5447 5F                   pop         edi
001E5448 5E                   pop         esi
001E5449 5B                   pop         ebx //pop就是出栈的意思,esp此时指向ebx下面的空间,这三个地址相当于被回收了
001E544A 81 C4 E4 00 00 00    add         esp,0E4h
001E5450 3B EC                cmp         ebp,esp
001E5452 E8 97 BE FF FF       call        __RTC_CheckEsp (01E12EEh)
001E5457 8B E5                mov         esp,ebp
001E5459 5D                   pop         ebp
001E545A C3                   ret
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 c语言