早上翻看兩年前做模擬器時的資料,在Marat Fayzullin的一篇How To Write a Computer Emulator文章中提及for(;;)和while(1)的差別——某些編譯器會生成檢測1是否爲真的代碼(some compilers will generate code checking whether 1 is true or not.)。
下午在網上又看到有人問這道題,於是想試着看看VC6的C++編譯器CL.exe是不是把while(1)優化成了和for(;;)一樣的彙編代碼?
從反彙編的代碼可以看出,while(1)確實做了判斷test eax,eax,根據判斷的結果選擇不同的跳轉方向。而for(;;)只是一句無條件轉移jmp main+18h。看來for(;;)的效率還是最高的。
至於這種問題,究竟有沒有意義,在當前狀態下,做過諸如模擬器、虛擬機或者對於實時性要求比較高的東西的話,還是會有很深的體會的。
/********************Zhu Zhenlong 2008-10-27 VC6.0********************/
void main()
{
for(;;);
}
1: void main()
2: {
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,40h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-40h]
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
3: for(;;);
00401028 jmp main+18h (00401028)
/********************Zhu Zhenlong 2008-10-27 VC6.0********************/
void main()
{
while(1);
}
1: void main()
2: {
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,40h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-40h]
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
3: while(1);
00401028 mov eax,1
0040102D test eax,eax
0040102F je main+23h (00401033)
00401031 jmp main+18h (00401028)
4: }
00401033 pop edi
00401034 pop esi
00401035 pop ebx
00401036 mov esp,ebp
00401038 pop ebp
00401039 ret
附:VC下看彙編代碼的設置方式
Project->Settings...
C/C++ tab
Category:Choose Listing Files
Listing file type
select "Assembly with source code"
然後Go->Disassembly,就可以了。