堆与栈存储效率的一点理解

来源:互联网 发布:php redis抢红包源代码 编辑:程序博客网 时间:2024/05/29 14:37

http://wenku.baidu.com/view/e180b4df5022aaea998f0f36.html

这篇文章上关于堆和栈的区别加以阐述,其中提到的堆与栈的存储效率的地方,通过自己查看汇编代码,把自己的理解汇总如下,算是对以上这篇文章的补充:

还是引用这个经典的例子:

#include <stdio.h>
void main() 

char a = 1; 
char c[] = "1234567890"; 
char *p ="1234567890"; 
a = c[1]; 
a = p[1]; 
return; 

整个代码的反汇编代码如下:

1:    #include <stdio.h>
2:    void main()
3:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,54h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-54h]
0040101C   mov         ecx,15h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
4:    char a = 1;
00401028   mov         byte ptr [ebp-4],1
5:    char c[] = "1234567890";
0040102C   mov         eax,[string "1234567890" (0042201c)]
00401031   mov         dword ptr [ebp-10h],eax
00401034   mov         ecx,dword ptr [string "1234567890"+4 (00422020)]
0040103A   mov         dword ptr [ebp-0Ch],ecx
0040103D   mov         dx,word ptr [string "1234567890"+8 (00422024)]
00401044   mov         word ptr [ebp-8],dx
00401048   mov         al,[string "1234567890"+0Ah (00422026)]
0040104D   mov         byte ptr [ebp-6],al
6:    char *p ="1234567890";
00401050   mov         dword ptr [ebp-14h],offset string "1234567890" (0042201c)
7:    a = c[1];
00401057   mov         cl,byte ptr [ebp-0Fh]
0040105A   mov         byte ptr [ebp-4],cl
8:    a = p[1];
0040105D   mov         edx,dword ptr [ebp-14h]
00401060   mov         al,byte ptr [edx+1]
00401063   mov         byte ptr [ebp-4],al
9:    return;
10:   }
00401066   pop         edi
00401067   pop         esi
00401068   pop         ebx
00401069   mov         esp,ebp
0040106B   pop         ebp
0040106C   ret

这里“1234567890”是一个字符串常量,存放的位置在常量数据区(既不是堆也不是栈),此处的地址为0042201c

也就是说编译的时候这个字符串常量已经确定了,

针对这个例子

char c[] = "1234567890"; 

char *p ="1234567890"; 

前后两个“1234567890”就是同一个字符串常量,存放在编译时确定的常量数据区里,

运行的时候再用这个常量字符串对c赋值,而第二种使用的时候先把指针值读到edx中,再根据edx读取字符。

如果换成下面的例子:

char c[] = "aaaaa"; 

char *p ="1234567890"; 

因为两个字符串不同,就存在常量数据区的不同位置。

汇编部分如下:

5:    char c[] = "aaaaa";
0040102C   mov         eax,[string "aaaaa" (00422028)]
00401031   mov         dword ptr [ebp-0Ch],eax
00401034   mov         cx,word ptr [string "aaaaa"+4 (0042202c)]
0040103B   mov         word ptr [ebp-8],cx
6:    char *p ="1234567890";
0040103F   mov         dword ptr [ebp-10h],offset string "1234567890" (0042201c)


原创粉丝点击