C语言探究 第一课 字符串数组篇
先上C语言 再上反汇编程序代码:
int _tmain(int argc, _TCHAR* argv[]) { char str[]="user32"; //char *str="user32" return 0; }
程序代码:
text:004117C0 .text:004117C0 push ebp .text:004117C1 mov ebp, esp .text:004117C3 sub esp, 0D4h .text:004117C9 push ebx .text:004117CA push esi .text:004117CB push edi .text:004117CC lea edi, [ebp+var_D4] .text:004117D2 mov ecx, 35h .text:004117D7 mov eax, 0CCCCCCCCh .text:004117DC rep stosd .text:004117DE mov eax, __security_cookie ; 0BB40E64Eh .text:004117E3 xor eax, ebp .text:004117E5 mov [ebp+var_4], eax .text:004117E8 mov eax, dword ptr ds:aUser32 ; "user32" 此处可以看到 .text:004117ED mov [ebp+var_10], eax "user" .text:004117F0 mov cx, word ptr ds:aUser32+4 .text:004117F7 mov [ebp+var_C], cx "32" .text:004117FB mov dl, byte ptr ds:aUser32+6 .text:00411801 mov [ebp+var_A], dl 0 上面代码为 char str[]="user32" 的反汇编,可以看到 user32是被放到了栈中的 .text:00411804 xor eax, eax .text:00411806 push edx .text:00411807 mov ecx, ebp .text:00411809 push eax .text:0041180A lea edx, dword_411828 .text:00411810 call j__RTC_CheckStackVars .text:00411815 pop eax .text:00411816 pop edx .text:00411817 pop edi .text:00411818 pop esi .text:00411819 pop ebx .text:0041181A mov ecx, [ebp+var_4] .text:0041181D xor ecx, ebp .text:0041181F call j___security_check_cookie .text:00411824 mov esp, ebp .text:00411826 pop ebp .text:00411827 retn .text:00411827 wmain endp
下面是另外一个版本
程序代码:
int _tmain(int argc, _TCHAR* argv[]) { //char str[]="user32"; char *str="user32"; return 0; }
程序代码:
push ebp mov ebp, esp sub esp, 0CCh push ebx push esi push edi lea edi, [ebp+var_CC] mov ecx, 33h mov eax, 0CCCCCCCCh rep stosd mov [ebp+var_8], offset aUser32 ; "user32" 此处为char *str="user32" xor eax, eax pop edi pop esi pop ebx mov esp, ebp pop ebp retn wmain endp
总结 char str[]="user32" 和 char *str="user32"两个
1.两个操作的数据来源均来自于数据段
2.前者用mov指令将指定字符串 存放到了栈中 进行访问,后者直接将数据的地址存放到栈中用地址间接进行访问
3.采用前者进行操作容易产生栈溢出的错误 ,后者是不会的 所以用后者进行操作是比较安全和妥当的
4.前者数据初始化慢 后者初始化快
[ 本帖最后由 zhu224039 于 2014-6-7 15:35 编辑 ]