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的汇编代码,所以更推荐使用结构体的直接赋值(注意,这里的结构体是指没有重载赋值函数的)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值