早上翻看两年前做模拟器时的资料,在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,就可以了。