函数调用过程解析:

代码:

#include <stdio.h> 
#include <stdlib.h>
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int ret = Add(a, b);
printf("ret = %d\n", ret);
system("pause");
return 0;
}

main函数在  __tmain CRTStartup 函数中调用的,而__tmain CRTStartup 函数是在main CRTStartup被调用的。

反汇编代码:

1. 从main函数的地方开始,要展开main函数的调用就得为main函数创建栈帧,那我们先来看main函数栈帧的创建。

int main()
{
001E1420  push        ebp  //把ebp压入栈
001E1421  mov         ebp,esp  //把esp的值赋给ebp,给ebp重新赋值
001E1423  sub         esp,0E4h  //给esp减去一个十六进制数0E4h,产生新的esp
001E1429  push        ebx  //把ebx压入栈
001E142A  push        esi  //把esi压入栈
001E142B  push        edi  //把edi压入栈
001E142C  lea         edi,[ebp-0E4h]  //lea 加载有效地址,把[ebp-0E4h]放入edi里去
001E1432  mov         ecx,39h //把39h放到ecx里
001E1437  mov         eax,0CCCCCCCCh  //把随机值0CCCCCCCCh放到eax
001E143C  rep stos    dword ptr es:[edi]  //rep stos是重复存储,dword代表双字节;edi每次存储4个字节,即向下重复复制,赋值ecx次,赋值为eax
int a = 10;,
001E143E  mov         dword ptr [a],0Ah  //10放入a
int b = 20;
001E1445  mov         dword ptr [b],14h  //20 放入b
int ret = Add(a, b);
001E144C  mov         eax,dword ptr [b]  //把b放入eax
001E144F  push        eax                       //把eax压栈
001E1450  mov         ecx,dword ptr [a]  //把a放入ecx
001E1453  push        ecx                      //把ecx压栈
001E1454  call        _Add (01E10E6h)  //call调用,call指令下一跳指令的地址为调用函数的地址,调用ADD函数
001E1459  add         esp,8                    //esp加8
001E145C  mov         dword ptr [ret],eax  //把eax赋给ret
printf("ret = %d\n", ret);
001E145F  mov         esi,esp  //把esp赋给esi
001E1461  mov         eax,dword ptr [ret]  
001E1464  push        eax  
001E1465  push        1E5858h  
001E146A  call        dword ptr ds:[1E9118h]  
001E1470  add         esp,8  
001E1473  cmp         esi,esp  
001E1475  call        __RTC_CheckEsp (01E1140h)  
system("pause");
001E147A  mov         esi,esp  
001E147C  push        1E5864h  
001E1481  call        dword ptr ds:[1E9110h]  
001E1487  add         esp,4  
001E148A  cmp         esi,esp  
001E148C  call        __RTC_CheckEsp (01E1140h)  
return 0;
001E1491  xor         eax,eax  
}
001E1493  pop         edi  
001E1494  pop         esi  
001E1495  pop         ebx  
001E1496  add         esp,0E4h  
001E149C  cmp         ebp,esp  
001E149E  call        __RTC_CheckEsp (01E1140h)  
001E14A3  mov         esp,ebp  
001E14A5  pop         ebp  
001E14A6  ret  


int Add(int x, int y)
{
001E13D0  push        ebp  //ebp压栈
001E13D1  mov         ebp,esp  //把esp赋给ebp
001E13D3  sub         esp,0CCh  //esp减去0CCh
001E13D9  push        ebx  //ebx压栈
001E13DA  push        esi  //esi压栈
001E13DB  push        edi  //edi压栈
001E13DC  lea         edi,[ebp-0CCh]  //加载有效地址,把[ebp-0CCh]放入edi里
001E13E2  mov         ecx,33h  
001E13E7  mov         eax,0CCCCCCCCh  
001E13EC  rep stos    dword ptr es:[edi]  
int z = 0;
001E13EE  mov         dword ptr [z],0  //把z赋值为0
z = x + y;
001E13F5  mov         eax,dword ptr [x]  //把x赋给eax
001E13F8  add         eax,dword ptr [y]  //把y和eax相加
001E13FB  mov         dword ptr [z],eax  //把eax赋值给z
return z;
001E13FE  mov         eax,dword ptr [z]  //z赋值给eax,由eax带回
}

001E1401  pop         edi  //出栈
001E1402  pop         esi  //出栈
001E1403  pop         ebx  //出栈
001E1404  mov         esp,ebp  //把ebp赋值给esp
001E1406  pop         ebp  //出栈,回到main的ebp
001E1407  ret  


函数调用过程解析

函数调用过程解析

相关文章: