就用一个很简单的程序试试
int
main()
{
int
a[10] = {0};
return
0;
}
在int a[10] = {0};这行设置断点,
F5 开始调试
Alt+8 调出汇编标签
关键汇编如下:
4: int
a[10] = {0};
012B8238 mov
dword
ptr
[ebp
-30h],0
012B823F xor
eax
,eax
012B8241 mov
dword
ptr
[ebp
-2Ch],eax
012B8244 mov
dword
ptr
[ebp
-28h],eax
012B8247 mov
dword
ptr
[ebp
-24h],eax
012B824A mov
dword
ptr
[ebp
-20h],eax
012B824D mov
dword
ptr
[ebp
-1Ch],eax
012B8250 mov
dword
ptr
[ebp
-18h],eax
012B8253 mov
dword
ptr
[ebp
-14h],eax
012B8256 mov
dword
ptr
[ebp
-10h],eax
012B8259 mov
dword
ptr
[ebp
-0Ch],eax
额,一看之下是不是傻了眼?
难道{0}的作用只是简单的一个个将元素赋值?
而且SB式的一个个mov?
不是吧……
将数组大小改大一点看看,比如30
再看一下汇编代码:
4: int
a[30] = {0};
011D8238 mov
dword
ptr
[ebp
-80h],0
011D823F push
74h
011D8241 push
0
011D8243 lea
eax
,[ebp
-7Ch]
011D8246 push
eax
011D8247 call
@ILT+1180(_memset) (11D64A1h)
011D824C add
esp
,0Ch
这次没那么SB了,通过调用_memset(跟进去,其实还是调用memset)
而且是从第二个元素的地址开始的,第一个已经赋0了
74h(16) => 116(10) = 29 * 4 (一个int 4字节,即32位)
大概也就这样了,编译器先判断数组长度有没有大于默认的,
大于就使用memset,不然一个个mov……
这就好办了,以后知道调用的函数绝对的会先清零那数组的话,
就不要写{0}了,免得又浪费那么多CPU周期
不过就现在CPU来说,写上去或者又是一种保证,反正CPU速度那么牛了
不在意那么点东东
再试了下char类型,差不多的了
测试环境:VC++ 2010 (Debug) + Windows 7 Ultimate SP1
(Release貌似又不是这样,下回有空再玩玩)