就用一個很簡單的程序試試
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貌似又不是這樣,下回有空再玩玩)