VC++中结构体赋值和memcpy的比较

// Test1

typedef struct

{

int  nValue;

BYTE nValue2[4];

}ST_TEST;

 

int main()

{

ST_TEST sTest1 = {0};        

ST_TEST sTest2 = {0};

sTest2 = sTest1;

memcpy(&sTest2, &sTest1, sizeof(sTest1));

return 0;

}

 

// Disassembly

typedef struct

{

int  nValue;

BYTE nValue2[4];

}ST_TEST;

 

int main()

{

004196B0  push        ebp 

004196B1  mov         ebp,esp

004196B3  sub         esp,0E4h

004196B9  push        ebx 

004196BA  push        esi 

004196BB  push        edi 

004196BC  lea         edi,[ebp-0E4h]

004196C2  mov         ecx,39h

004196C7  mov         eax,0CCCCCCCCh

004196CC  rep stos    dword ptr es:[edi]

004196CE  mov         eax,dword ptr [___security_cookie (428080h)]

004196D3  xor         eax,ebp

004196D5  mov         dword ptr [ebp-4],eax

ST_TEST sTest1 = {0};        

004196D8  mov         dword ptr [ebp-10h],0

004196DF  xor         eax,eax

004196E1  mov         dword ptr [ebp-0Ch],eax

ST_TEST sTest2 = {0};

004196E4  mov         dword ptr [ebp-20h],0

004196EB  xor         eax,eax

004196ED  mov         dword ptr [ebp-1Ch],eax

sTest2 = sTest1;

004196F0  mov         eax,dword ptr [ebp-10h]

004196F3  mov         dword ptr [ebp-20h],eax

004196F6  mov         ecx,dword ptr [ebp-0Ch]

004196F9  mov         dword ptr [ebp-1Ch],ecx

memcpy(&sTest2, &sTest1, sizeof(sTest1));

004196FC  push        8   

004196FE  lea         eax,[ebp-10h]

00419701  push        eax 

00419702  lea         ecx,[ebp-20h]

00419705  push        ecx 

00419706  call        @ILT+980(_memcpy) (4113D9h)

0041970B  add         esp,0Ch

 

return 0;

0041970E  xor         eax,eax

}

 

 

// Test2

typedef struct

{

int  nValue;

BYTE bValue[4092];

}ST_TEST;

 

int main()

{

ST_TEST sTest1 = {0};        

ST_TEST sTest2 = {0};

sTest2 = sTest1;

memcpy(&sTest2, &sTest1, sizeof(sTest1));

 

return 0;

}

 

 

// Disassembly

typedef struct

{

int  nValue;

BYTE bValue[4092];

}ST_TEST;

 

int main()

{

004196B0  push        ebp 

004196B1  mov         ebp,esp

004196B3  mov         eax,20D4h

004196B8  call        @ILT+415(__chkstk) (4111A4h)

004196BD  push        ebx 

004196BE  push        esi 

004196BF  push        edi 

004196C0  lea         edi,[ebp-20D4h]

004196C6  mov         ecx,835h

004196CB  mov         eax,0CCCCCCCCh

004196D0  rep stos    dword ptr es:[edi]

004196D2  mov         eax,dword ptr [___security_cookie (428080h)]

004196D7  xor         eax,ebp

004196D9  mov         dword ptr [ebp-4],eax

ST_TEST sTest1 = {0};        

004196DC  mov         dword ptr [ebp-1008h],0

004196E6  push        0FFCh

004196EB  push        0   

004196ED  lea         eax,[ebp-1004h]

004196F3  push        eax 

004196F4  call        @ILT+510(_memset) (411203h)

004196F9  add         esp,0Ch

ST_TEST sTest2 = {0};

004196FC  mov         dword ptr [ebp-2010h],0

00419706  push        0FFCh

0041970B  push        0   

0041970D  lea         eax,[ebp-200Ch]

00419713  push        eax 

00419714  call        @ILT+510(_memset) (411203h)

00419719  add         esp,0Ch

sTest2 = sTest1;

0041971C  push        1000h

00419721  lea         eax,[ebp-1008h]

00419727  push        eax 

00419728  lea         ecx,[ebp-2010h]

0041972E  push        ecx 

0041972F  call        @ILT+980(_memcpy) (4113D9h)

00419734  add         esp,0Ch

memcpy(&sTest2, &sTest1, sizeof(sTest1));

00419737  push        1000h

0041973C  lea         eax,[ebp-1008h]

00419742  push        eax 

00419743  lea         ecx,[ebp-2010h]

00419749  push        ecx 

0041974A  call        @ILT+980(_memcpy) (4113D9h)

0041974F  add         esp,0Ch

 

return 0;

00419752  xor         eax,eax

}


通过上面的的两份测试代码,我们可以看出,结构的直接赋值(默认结构体赋值函数)memcpy之间的异同.

1,结构体小于4096,赋值是通过结构体中每个变量的赋值来完成的.

2,结构体大于等于4096,结构体赋值与memcpy的效果是一样的.因为我们通过代码的反汇编,可以看出编译器已经将代码优化成一样的汇编代码了.

所以,理论上来说,针对结构体调用memcpy的效果与直接赋值基本上是一样的.

而且按照汇编的结果,直接赋值的汇编代码少于memcpy的汇编代码,所以更推荐使用结构体的直接赋值(注意,这里的结构体是指没有重载赋值函数的)

你可能感兴趣的:(VC++)