// 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, 39 h 004196C7 mov eax, 0 CCCCCCCCh 004196CC rep stos dword ptr es: [edi] 004196CE mov eax, dword ptr [___ security_cookie (428080 h)] 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, 835 h 004196CB mov eax, 0 CCCCCCCCh 004196D0 rep stos dword ptr es: [edi] 004196D2 mov eax, dword ptr [___ security_cookie (428080 h)] 004196D7 xor eax, ebp 004196D9 mov dword ptr [ebp-4], eax ST_TEST sTest1 = {0 }; 004196DC mov dword ptr [ebp-1008h], 0 004196E6 push 0 FFCh 004196EB push 0 004196ED lea eax, [ebp-1004h] 004196F3 push eax 004196F4 call @ ILT + 510 (_ memset) (411203 h) 004196F9 add esp, 0Ch ST_TEST sTest2 = {0 }; 004196FC mov dword ptr [ebp-2010h], 0 00419706 push 0 FFCh 0041970B push 0 0041970D lea eax, [ebp-200Ch] 00419713 push eax 00419714 call @ ILT + 510 (_ memset) (411203 h) 00419719 add esp, 0Ch STest2 = sTest1; 0041971C push 1000 h 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 1000 h 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 }
From the two test codes above, we can see the similarities and differences between direct Structure assignment (default struct assignment function) and memcpy. In example 1, if the struct value is less than 4096, the value assignment is completed by the value assignment of each variable in the struct. In Example 2, when the struct value is greater than or equal to 4096, the struct value assignment has the same effect as memcpy. because we can see through the Code disassembly that the compiler has optimized the code into the same assembly code. Therefore, theoretically, the effect of calling memcpy for struct is basically the same as that of direct assignment. In addition, according to the assembly results, the compilation code with a direct value assignment is less than the compilation code of memcpy, so we recommend that you use a direct value assignment for the struct (note that the struct here refers to the absence of the overload assignment function) |