这里接着探求被调函数的返回值是如何传递到主调函数中的,下面为c程序。add函数通过直接返回a+b的,而add1函数先定义一个局部变量c,储存a+b的值,然后再返回c的值。其中a+b可以当成一个临时变量,其结果是暂时存放在寄存器中的(eax)。参照反汇编程序,可以看出函数的值并不是通过压栈、基址寻址的方式传递到被调函数中的,而是暂存在寄存器中,然后再mov到主调函数的变量中的。
c程序
#include<stdio.h>
int add(int a, int b)
{
return(a+b);//返回的是临时变量
}
int add1(int a, int b)
{
int c = a+b;
return(c);//返回的是函数的局部变量
}
void main()
{
int a = 2;
int b = 2;
int c,d;
c = add(a,b);
d = add1(a,b);
printf("%d,%d",c,d);
getchar();
}
反汇编
c = add(a,b);
0104144C mov eax,dword ptr [b]
0104144F push eax
01041450 mov ecx,dword ptr [a]
01041453 push ecx
01041454 call @ILT+215(_add) (10410DCh) //跳转到被调函数
01041459 add esp,8
0104145C mov dword ptr [c],eax //将a+b的值传递到main函数的变量c中
@ILT+215(_add):
010410DC jmp add (10413A0h)
int add(int a, int b)
{
010413A0 push ebp
010413A1 mov ebp,esp
010413A3 sub esp,0C0h
010413A9 push ebx
010413AA push esi
010413AB push edi
010413AC lea edi,[ebp-0C0h]
010413B2 mov ecx,30h
010413B7 mov eax,0CCCCCCCCh
010413BC rep stos dword ptr es:[edi]
return(a+b);//返回的是临时变量
010413BE mov eax,dword ptr [a]
010413C1 add eax,dword ptr [b] //在eax中完成运算和存储
}
010413C4 pop edi
010413C5 pop esi
010413C6 pop ebx
010413C7 mov esp,ebp
010413C9 pop ebp
010413CA ret
d = add1(a,b);
0104145F mov eax,dword ptr [b]
01041462 push eax
01041463 mov ecx,dword ptr [a]
01041466 push ecx
01041467 call @ILT+265(_add1) (104110Eh)
0104146C add esp,8
0104146F mov dword ptr [d],eax //函数的返回值还是通过寄存器进行传递的
@ILT+265(_add1):
0104110E jmp add1 (10413E0h)
int add1(int a, int b)
{
010413E0 push ebp
010413E1 mov ebp,esp
010413E3 sub esp,0CCh
010413E9 push ebx
010413EA push esi
010413EB push edi
010413EC lea edi,[ebp-0CCh]
010413F2 mov ecx,33h
010413F7 mov eax,0CCCCCCCCh
010413FC rep stos dword ptr es:[edi]
int c = a+b;
010413FE mov eax,dword ptr [a]
01041401 add eax,dword ptr [b]
01041404 mov dword ptr [c],eax //将a+b的结果存放到c中
return(c);//返回的是函数的局部变量
01041407 mov eax,dword ptr [c] //将a+b的结果存放到eax中
}
0104140A pop edi
0104140B pop esi
0104140C pop ebx
0104140D mov esp,ebp
0104140F pop ebp
01041410 ret