函数调用过程解析:
代码:
#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