上篇只是简单的说了一下Delphi迷你化程序的初级优化
这篇主要是说如何进行外部改变Delphi架构...
现在Delphi编译器本身已经优化的暂时到顶了.我们来看看
下面影响我们继续迷你化的是什么问题...
1.数据段和代码段的融合,还有没用的bss等等段
完全可以融合到一起
2.文件对齐,还有DOS Stub
在VC下我们可以很容易解决这个问题.谁让Borland的编译器技术很好,连接器技术确
。。。算了这个不是在我们考虑范围以内
我们来解决以上两个问题。
如果要解决这两个问题就要追忆。。。Delphi的发展史了。。。
(BTW:看来这丫~是彻底秀逗了...)
Delphi的编译器是Anders一手调教出来的...(我也不知道说什么好)
据说在Delphi老版本的时候是可以生成COFF格式的,关于这个问题
有一个彻底的项目...Ms-Rem大牛以前彻底研究过这个东西
还扔出一个演示品...由于当时的疏忽没有发现他使用的是Delphi3进行编译的
[见附件1]
由于Delphi3的特殊性造就了这个很奇怪的东西...兼容COFF的OMF???不明白
masm的link(polink)可以对其进行实施link操作
unit HelloWorld;
interface
Procedure Start;
implementation
function MessageBoxA(hWnd: cardinal; lpText, lpCaption: PChar; uType: Cardinal): Integer;
stdcall; external 'user32.dll' name '_MessageBoxA@16';
Procedure Start;
begin
MessageBoxA(0, 'Hello world!', nil, 0);
end;
end.
由于Delphi使用的是OMF结构...Delphi本身默认是产生dcu文件的
obj文件需要重新设置一下...看代码即可知道...
MASM中的默认库函数到处头部都是采用_MessageBoxA@16这样的结构
@16这个是传递参数的大小---SizeOf(DWORD) * 4
Win32下指针其实也是DWORD~不是吗?呵呵
根据这个obj进行一下连接操作
dcc32.exe -jP -$A-,B-,C-,D-,G-,H-,I-,J-,L-,M-,O+,P-,Q-,R-,T-,U-,V-,W+,X+,Y- HelloWorld.pas
link.exe /ALIGN:32 /FORCE:UNRESOLVED /SUBSYSTEM:WINDOWS /ENTRY:Start$qqrv HelloWorld.obj user32.lib /out:Hello.exe
/ALIGN:32 (这里最好修改为0x200)
/FORCE:UNRESOLVED(强制输出)
请使用delphi3进行编译...这里提供一个开发包...
[见附件2]
包括代码演示...请大家自行研究...
关于入口点/ENTRY:Start$qqrv
为什么采用pas而不是dpr,主要原因是因为..dpr的入口点是锁死的
就是@InitEXE...由于是不导出的所以没办法使用...
所以采用pas.那不是每次写代码都非常郁闷,还有Delphi3的优化
为了解决这两个问题,所以重新改变一下
masm 7.0的link具有重新创建obj的功能
这里使用这个方法...
Delphi 7依然可以创建。做一个通用工程来玩玩
总是用批处理不好讲究点实际开发。。来新建一个工程吧
[见附件2]
program Project1;
uses
Unit_Main;
begin
_entry();
end.
unit Unit_Main;
interface
function MessageBoxA(hWnd: cardinal; lpText, lpCaption: PChar; uType: Cardinal): Integer; stdcall; external 'user32.dll' name '_MessageBoxA@16';
procedure _entry();
implementation
procedure _entry();
begin
MessageBoxA(0, 'Hello World!', 'By Anskya', 0);
end;
end.
剩下的完全API就可以了(小心使用ZeroMemory,FillMemory,CopyMemory这三个函数,
Delphi为了编码效率把这两个函数给内嵌了...切忌切忌实在需要咱自己写,
要不然就自己GetProcAddress...).自己写函数声明吧...
_entry();这个名称是因为连接器把你输入入口函数名称加上_
不知道为啥这个习惯...
工程设置需要重新设置一下(Delphi默认是不会生成obj的)
Project Options->link
选择生成C++ object Files,Export All symbols
就可以生成我们需要的obj了...
为了减去不必要的转换麻烦,这里使用mickeylan 大侠为我们准备的rmcoff
为了减少大家的麻烦.发现这个简单的东西就没必要自己去写批处理了.吼吼
批处理代码如下(基本上是死代码..写好一次以后的随机修改就好了)
..\rmcoff\rmcoff.exe Unit_Main.obj Unit_Main.obj
..\small\link.exe /ALIGN:0x200 /SUBSYSTEM:windows /ENTRY:entry Unit_Main.obj ..\lib\user32.lib /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:_EXIT_=.text /MERGE:_INIT_=.text /SECTION:.text,RWEX /ignore:4033,4078,4108 /out:Hello.exe
pause
link编译说明:
这里的user32.lib链接库不是masm32\lib下的
这个链接库是重新创建的:
LINK -LIB -MACHINE:IX86 -DEF:KERNEL32.DEF
具体可以参考以前我写的文章<<浅谈连接库函数的声明与创建>>
http://bbs.pediy.com/showthread.php?t=25555
这里编译是完全没问题了(看...附件中的样式代码)
Delphi 7 编译 MASM Link
如果你觉得体积还是不够小请调整:/ALIGN:0x200,可以修改为4
那编译出来的效果就是传说中的680字节了~不过为了兼容Win9x,最好不要修改
好了至此~小萝莉已经被我们调教的差不多了...下面你还想干什么???
//====================
哦我知道了~你们是说这样写代码太痛苦了是吧...的确每个函数都要声明...
后才可以使用...再次教大家一个秘籍吧...
Borland Format For COFF...吼吼~
意思就是说创建一个Borland格式的到处头部的COFF格式LIB
听起来有点怪异哦~就是取消掉_,@16等特征的纯正COFF LIB...
使用大牛Vortex的工具...来创建我们需要的LIB格式
def2lib user32.def -nod
user32.def
LIBRARY user32
EXPORTS
"MessageBoxA"
你可以自己写一个遍历导出表的程序来自动生成这个文件...
修改代码如下
unit Unit_Main;
interface
uses
Windows;
procedure _entry();
implementation
procedure _entry();
begin
MessageBox(0, 'Hello World!', 'By Anskya', 0);
ExitProcess(0);
end;
end.
批处理代码
..\rmcoff\rmcoff.exe Unit_Main.obj Unit_Main.obj
..\small\link.exe /ALIGN:0x200 /SUBSYSTEM:windows /ENTRY:entry Unit_Main.obj ..\def2lib\kernel32.lib ..\def2lib\user32.lib /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:_EXIT_=.text /MERGE:_INIT_=.text /SECTION:.text,RWEX /ignore:4033,4078,4108 /out:Project2.exe
pause
这样就可以直接引用Windows.pas了~~以后再也不需要自己声明头部了...感谢Vortex
赐予我们这麽好的一个工具...感谢...
如果是多个单元的编译的话
请在批处理中增加你要处理的obj...
此次调教活动得以顺利展开感谢以下大牛们:
Anders,EliCZ,Vortex,Ms-Rem,mickeylan
再次感谢大家顺利看完这篇文章所有工具和代码实例都在附件中请大家自行查看
谢谢大家...祝大家春节愉快,合家欢乐
上传的附件: