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

来源:互联网 发布:淘宝分销商 编辑:程序博客网 时间:2024/06/07 01:29

函数的调用过程、栈帧的创建、销毁
以下面的程序为例:

#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                   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函数的空间地址加载给edi001E53D2 B9 39 00 00 00       mov         ecx,39h  //将39h给ecx001E53D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh //将0CCCCCCCCh 给eax001E53DC 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