首页
社区
课程
招聘
瘦身你的执行文件
发表于: 2006-12-26 23:39 5131

瘦身你的执行文件

2006-12-26 23:39
5131
这篇文章转自网上,发现好东西兴奋的同时,不敢独享,如果谁已经看过 ,请不要BS我。
在网上,有好多绿色软件,不仅功能强大,而且软件本身的体积非常小。有的通常只在几十K左右。那他们是怎么做到把软件做的怎么小的呢?现在我手把手的告诉你如何通过修改程序的编译选项来瘦身你的执行文件。
先看一个最典型的程序:
#include <stdio.h>
int main()
{
printf("Hello, World!\n");
return 0;
}
上面的程序之所以被称之为典型,是因为他有如下的内容:
1、系统函数调用:printf
2、有静态数据段
好,现在把此文件放到VisualStudio6.0中进行编译,看看文件有多大。
1、用VisualStudio6.0打开HelloWorld.cpp文件,直接按F7。然后点击OK,生成Project文件,然后进行编译。编译完成了以后,看看Debug目录下的执行文件的大小,为172,096Bytes。
2、刚才编译的Debug文件,现在修改成Release文件看看。选择Win32 Release,再编译。察看执行文件大小,现在成了40,960Bytes。看来Release版本的要比Debug的小。
3、检查代码优化:发现执行文件的优化是Maximize Speed。那么修改成MinimizeSize看看。重新编译,得到执行文件的大小为:40,960Bytes。看来大小没什么变化。其实这是由于我们的代码本身太小的缘故,导致即使变化了也看不出来。
4、想想我们程序的main函数是由CRT类库进行引导的。在我们现在的设定当中,由于采取的是系统缺省的编译连接方式(缺省为编译为Single Thread,StaticLibrary),所以,在我们的执行文件当中,包含了CRT的二进制代码。好,修改编译选项:C/C++ => Category:Code Generation => Use run-time
library:MutiThreaded Dll。编译看看:执行文件大小变成了16,384Bytes。
5、刚才的设定确实不错,一下子把执行文件大小减小到了16K。现在用UltraEdit看看执行文件都是些什么内容。结果大吃一惊:基本上都是0。看来这个有减小的必要了。都知道,执行文件都有自己的代码段,数据段等等,每个段的大小也是采用编译器缺省设定的。好,我们来修改一下段的大小看看:
5.1 连接选项中有一个是/opt:nowin98,意思是将段的大小设定成为Win2000适应的。编译看看:哇塞,变成了2,560byte。看来这个选项确实把文件变小了N多。
5.2 在查察连接选项中还有没有什么特别的。发现/align:xx还可以将段大小缩小。通过UltraEdit察看刚才/opt:nowin98编译出来的文件,发现每个段的大小都是4K的整数倍。看来/align:xx还有减小的趋势。试一把再说:添加连接选项:/align:16(这个大小已经是能够设定的最小的了)。看看结果:1,408Bytes。厉害,现在代码更小了。
5.3 现在回想起来,执行文件大小有数据段,执行代码段等等,如果把这些段都合并起来,是不是就会把段之间的冗余有减小了呢?再试试看:添加选项:/merge:.data=.text /merge:.rdata=.text。再看看文件大小:1,328bytes。真的很不错了。
6、刚才的设定确实不错,似乎达到了我们想要的极限了。但是回头想一下,如果没有CRT库的话,会不会更小了?实际上确实这样。添加连接选项: /entry:main,把入口地址直接指向我们的main函数看看。得到592Bytes。
最终我们得到我们最后的大小592Bytes了。我想这也许是我们通过编译器能够编译出来的最小的代码了。
结论:
通过上述的步骤,我们了解了如何修改那些编译连接选项来达到执行文件瘦身的目的。但是,通常来讲,在我们的Release文件当中,并不需要如此小的执行文件。如果想达到瘦身的目的,修改为library:MutiThreaded Dll和添加/opt:nowin98已经是很好的选择了。其他别的选项在编译的时候或多或少的有警告出现,而且,带有那些编译选项编出来的执行文件也不一定在各个平台上能够适用。
另外:如果你的执行文件即使通过了这些设定还是比较大的话,也可以通过一些EXE文件压缩工具来进行压缩。比如UPX等等。在此不再细说了。
以上部分的不足之处,还请多多指正。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 201
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
http://bbs.pediy.com/showthread.php?threadid=19823
2006-12-27 00:17
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
是个不错的文章,短短几句话把所有从编译器角度的大小优化都说出来了.
这就是VC编译器的一大优点吧.那些BCB和Delphi的fans就只能望洋兴叹了.
2006-12-27 09:22
0
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
4
千万合并代码段呀!!!不然在XP SP2,你会发现那是致命的.
2006-12-27 10:41
0
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
最初由 vcmfc 发布
千万合并代码段呀!!!不然在XP SP2,你会发现那是致命的.


做3721的牛人也?看雪了啊
2006-12-27 15:57
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
最初由 vcmfc 发布
千万合并代码段呀!!!不然在XP SP2,你会发现那是致命的.

合并代码段是可以的,前提是要把段属性全设置上,至少RWEC都应该有.
2006-12-27 18:17
0
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
7
好东东,消化它
2006-12-27 22:41
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
用这种方法,对exe编译减少大小效果挺明显的,对dll的效果不是很好,从90K降到了70K
2006-12-28 15:39
0
雪    币: 234
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好文章!
一直在寻找!
2006-12-30 12:04
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
好文章啊!
顶!
2007-1-1 13:36
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
学习了。好好研究一下。
2007-1-1 15:16
0
雪    币: 428
活跃值: (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习了!
2007-1-3 14:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
解惑的好东西

谢谢lz分享^_^
2007-1-8 14:52
0
游客
登录 | 注册 方可回帖
返回
//