不同编译器生成的结果不同,但本质都是通过寄存器或内存复制,本测试只是为了了解结构体在作为局部变量时的参数传递与返回的本质,实际使用中,最好定义为全局变量
结构体传参:
# include<stdio.h>
struct st
{
char a;
short b;
int c;
int d;
int e;
};
void Function(st s)
{
}
int main(int argc, char* argv[])
{
st s;
s.a = 1;
s.b = 2;
s.c = 3;
s.d = 4;
s.e = 5;
Function(s);
return 0;
}
反汇编:
1.vs2017测试结果,使用寄存器传递地址
Function(s);
008A1740 sub esp,10h
008A1743 mov eax,esp
008A1745 mov ecx,dword ptr [s]
008A1748 mov dword ptr [eax],ecx
008A174A mov edx,dword ptr [ebp-10h]
008A174D mov dword ptr [eax+4],edx
008A1750 mov ecx,dword ptr [ebp-0Ch]
008A1753 mov dword ptr [eax+8],ecx
008A1756 mov edx,dword ptr [ebp-8]
008A1759 mov dword ptr [eax+0Ch],edx
008A175C call Function (08A10A5h)
008A1761 add esp,10h
2.vc++6.0测试结果,直接使用rep stos指令,在内存内复制
12: void Function(st s)
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,40h
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-40h]
0040102C mov ecx,10h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
00401038 pop edi
00401039 pop esi
0040103A pop ebx
0040103B mov esp,ebp
0040103D pop ebp
0040103E ret
结构体返回值:
# include<stdio.h>
struct st
{
char a;
short b;
int c;
int d;
int e;
};
st Function()
{
st s;
s.a = 1;
s.b = 2;
s.c = 3;
s.d = 4;
s.e = 5;
return s;
}
int main(int argc, char* argv[])
{
st a = Function();
return 0;
}
反汇编:
vs2017测试结果,把Function函数的返回值的地址放在eax
st a = Function();
0106171E lea eax,[ebp-104h] //外层函数用来接收返回值的地址
01061724 push eax
01061725 call Function (01061366h)
0106172A add esp,4
0106172D mov ecx,dword ptr [eax]
0106172F mov dword ptr [ebp-0ECh],ecx
01061735 mov edx,dword ptr [eax+4]
01061738 mov dword ptr [ebp-0E8h],edx
0106173E mov ecx,dword ptr [eax+8]
01061741 mov dword ptr [ebp-0E4h],ecx
01061747 mov edx,dword ptr [eax+0Ch]
0106174A mov dword ptr [ebp-0E0h],edx
01061750 mov eax,dword ptr [ebp-0ECh]
01061756 mov dword ptr [a],eax
01061759 mov ecx,dword ptr [ebp-0E8h]
0106175F mov dword ptr [ebp-10h],ecx
01061762 mov edx,dword ptr [ebp-0E4h]
01061768 mov dword ptr [ebp-0Ch],edx
0106176B mov eax,dword ptr [ebp-0E0h]
01061771 mov dword ptr [ebp-8],eax
vc++6.0测试结果,把Function函数的返回值的地址放在eax
st a = Function();
0040D4D8 lea eax,[ebp-30h] //外层函数用来接收返回值的地址
0040D4DB push eax
0040D4DC call @ILT+20(Function) (00401019)
0040D4E1 add esp,4
0040D4E4 mov ecx,dword ptr [eax]
0040D4E6 mov dword ptr [ebp-20h],ecx
0040D4E9 mov edx,dword ptr [eax+4]
0040D4EC mov dword ptr [ebp-1Ch],edx
0040D4EF mov ecx,dword ptr [eax+8]
0040D4F2 mov dword ptr [ebp-18h],ecx
0040D4F5 mov edx,dword ptr [eax+0Ch]
0040D4F8 mov dword ptr [ebp-14h],edx
0040D4FB mov eax,dword ptr [ebp-20h]
0040D4FE mov dword ptr [ebp-10h],eax
0040D501 mov ecx,dword ptr [ebp-1Ch]
0040D504 mov dword ptr [ebp-0Ch],ecx
0040D507 mov edx,dword ptr [ebp-18h]
0040D50A mov dword ptr [ebp-8],edx
0040D50D mov eax,dword ptr [ebp-14h]
0040D510 mov dword ptr [ebp-4],eax