先看说产生一个hello world大小的那例子。Turbo Pascal产生的hello world的确小,但是那是win32程序还是dos程序?dos程序去掉一个简单的MZ Header以后就没有任何多余的信息了,这里的多余指不能从source对应的东西,比如分配堆之类的。当然,如果是保护模式的,情况又不一样,但我不相信作者说的为保护模拟下的hello world。
看看win32下各类编译器,他们产生的代码要有:MZ Header、Dos STUB 、PE Header 、OP Header 、Section Table,然后是各个节,节里面还有诸如导入导出表、资源、线程本地存储等数据。加上一个进程被Loader加载以后需要自己去分配堆,在结束时候需要自己去结束进程,做清理工作。这种情况下用DOS程序大小比较win32程序,得出Borland比MS的东西,只能说是胡闹。
再看下一个例子:
void foo(void)
{
int i, j;
for (i = 0; i < 16; i++) j = j + i;
}
文中说:
C++ Builder 5生成的代码(最大速度优化):
00401535 33c0 xor eax,eax 1
00401537 40 inc eax 1
00401538 83f810 cmp eax,0x10 1
0040153b 7cfa jl -0x06 0 (可并行)
没有做加法为何要保留这个循环?很简单,Borland无法优化掉这个循环。
再来看看VC,为何用VC5?莫非作者任何VC5和BCB5一个年代的?为何不换四年前的VC6?
我初中2年级上物理课就知道写试验报告要写设备型号与编号,可惜作者为了达到某些目的没有写,或许用个人版和BCB企业版比较
VC6 企业版+sp5,关闭其它优化,仅打开全局优化,然后看看反编译结果。
我用的代码是
void foo()
{
int i,j;
for(i=0;i<16;i++)
j = j + 1;
}
int main(int argc, char* argv[])
{
foo();
}
结果:
.text:00401020 public start
.text:00401020 start proc near
.text:00401020
.text:00401020 var_20 = dword ptr -20h
.text:00401020 var_1C = dword ptr -1Ch
.text:00401020 var_18 = dword ptr -18h
.text:00401020 var_14 = dword ptr -14h
.text:00401020 var_4 = dword ptr -4
.text:00401020
.text:00401020 push ebp ; sub_401020
.text:00401021 mov ebp, esp
.text:00401023 push 0FFFFFFFFh
.text:00401025 push offset unk_4050A0
.text:0040102A push offset __except_handler3
.text:0040102F mov eax, large fs:0
.text:00401035 push eax
.text:00401036 mov large fs:0, esp
.text:0040103D sub esp, 10h
.text:00401040 push ebx
.text:00401041 push esi
.text:00401042 push edi ; ExceptionInfo
.text:00401043 mov [ebp+var_18], esp
.text:00401046 call ds:GetVersion
.text:0040104C xor edx, edx
.text:0040104E mov dl, ah
.text:00401050 mov dword_4084E4, edx
.text:00401056 mov ecx, eax
.text:00401058 and ecx, 0FFh
.text:0040105E mov dword_4084E0, ecx
.text:00401064 shl ecx, 8
.text:00401067 add ecx, edx
.text:00401069 mov dword_4084DC, ecx
.text:0040106F shr eax, 10h
.text:00401072 mov dword_4084D8, eax
.text:00401077 push 0
.text:00401079 call sub_401B26
.text:0040107E pop ecx
.text:0040107F test eax, eax
.text:00401081 jnz short loc_40108B
.text:00401083 push 1Ch ; Overlapped
.text:00401085 call sub_401124 ; _fast_error_exit
.text:0040108A pop ecx
.text:0040108B
.text:0040108B loc_40108B: ; CODE XREF: start+61j
.text:0040108B and [ebp+var_4], 0
.text:0040108F call __ioinit
.text:00401094 call ds:GetCommandLineA
.text:0040109A mov dword_4089D8, eax
.text:0040109F call ___crtGetEnvironmentStringsA
.text:004010A4 mov dword_4084C0, eax
.text:004010A9 call __setargv
.text:004010AE call __setenvp
.text:004010B3 call __cinit
.text:004010B8 mov eax, dword_4084F4
.text:004010BD mov dword_4084F8, eax
.text:004010C2 push eax
.text:004010C3 push dword_4084EC
.text:004010C9 push dword_4084E8
.text:004010CF call j_unknown_libname_1 //main()
.text:004010D4 add esp, 0Ch
.text:004010D7 mov [ebp+var_1C], eax
.text:004010DA push eax ; int
.text:004010DB call _exit
.text:00401010 j_unknown_libname_1 proc near ; CODE XREF: start+AFp
.text:00401010 jmp unknown_libname_1
.text:00401010 j_unknown_libname_1 endp
.text:00401000 unknown_libname_1 proc near ; CODE XREF: j_unknown_libname_1j
.text:00401000 retn //foo()整个被优化掉了?
.text:00401000 unknown_libname_1 endp
从上面的例子也可以看出,用win32比DOS的Image大小多可笑吧?
最后说Delphi,我从来没有看过delphi,和不打算考虑VB一样,这种东西无非希望让你上他的贼船,然后嘿嘿,我实在不知道投资这种垄断的语言工具,如同Borland掐住了你的脖子,还说快乐.......
btw:我做过更加详细的关于C++各语言特性在win32+VC的实现的观察,包括诸如异常处理、虚函数实现、构造析构函数机制等等,如果老兄有兴趣,不妨交流这方面的东西。
-------------------------------------------------------------------------------------------
这个家伙很懒,什么也没留下......