2009-06-08 121 views
12

最近我一直在维护用VC++ 6.0编写的遗留项目。代码使用了这种编译器的许多独特特性,将它移植到更新的标准编译器中,这被证明是一项艰巨的任务。OMF和COFF格式有什么区别?

其中的项目代码千行,有四个汇编文件。出于某种原因,我不明白,也没有MASM615或TASM能够编译它们(他们发送错误),但我有目标文件。然而,当我链接库我得到一个消息

警告LNK4033:从OMF转换对象格式COFF

库按预期工作,但我一直在想,什么是这些二进制文件之间的差异格式,或者如果我期望从这种转换中看到一些丑陋的东西。

+1

请看http://www.iecc.com/linker/linker03.html。 – avakar 2009-06-08 19:48:21

+0

@avakar:为什么不把这个链接倒入正确的答案? – xtofl 2009-06-08 20:10:00

回答

14

回答缺口出来的“MetaWINDOW常见问题 - OMF VS COFF目标文件Formats.htm”

由于PC文明向上的黎明到了时间的Microsoft Win32编程工具来了,生产的几乎所有的PC编译器的目标文件使用英特尔目标模块格式(OMF)标准。后来,英特尔推出了386个处理器和32位保护模式,此时他们还将OMF规范扩展到了32位,从而形成了“OMF-386”,成为大多数PC保护模式环境的标准。大约在同一时间,最初的Windows NT开发团队也在设计代码,不仅用于英特尔处理器,还用于支持其他供应商的处理器。微软NT团队选择了被称为通用对象文件格式(COFF)从UNIX系统V COFF对象模块的官方目标代码格式导出的更便携的对象模块格式后来成为所有微软的Win32开发工具的事实标准,并获得在正在格式更接近于移植可执行文件的优势 - 为Win32本机可执行文件格式(COFF格式的连接要少得多的工作,以创建比从OMF格式文件COFF文件32位的EXE或DLL)。

正如有OMF-和COFF格式的目标文件(.OBJ的),还有OMF和COFF格式库文件(.LIB的)。幸运的是,这些库基本上只是对象文件的一个集合,还有一些头文件信息可以让链接器确定从库中使用哪些对象文件。然而,为了使事情变得困难,OMF和COFF都使用相同的文件扩展名.obj和.lib来引用两种不同类型的对象和库文件格式(因为这样你就不能只看文件扩展名告诉对象模块或库文件是否为OMF或COFF)。

从不同的编译器厂商混合对象文件和库文件的问题是,有些供应商支持COFF,其他供应商使用OMF,和几个可以同时处理。例如,Borland仍然使用OMF目标文件和库,而微软的32位编译器生成COFF格式文件。在编译和链接Windows应用程序时,Watcom C/C++ v11.0似乎更喜欢COFF,但生成OMF目标文件以与其DOS4GW 32位保护模式DOS扩展程序一起使用。除此之外,默认情况下,Microsoft MASM 6.13会生成OMF文件,但使用/ coff开关可以发出COFF目标文件。

当谈到时间不同格式的链接文件,不同接头做不同的事情。例如,Microsoft Visual C/C++链接器是为COFF格式的目标文件和库而设计的,但如果需要,它会尝试将OMF目标文件转换为COFF文件。这在某些情况下可行,但不幸的是,Microsoft LINK不支持所有OMF记录类型,因此在许多情况下,链接器在给出OMF格式对象文件时可能仍会失败。另外,虽然Microsoft LINK尝试对OMF目标文件提供一些支持,但它将拒绝处理任何OMF格式库。其他连接器,如Borland的TLINK,是为OMF目标文件设计的,并且同样拒绝使用COFF格式的对象或库文件。某些DOS扩展器和嵌入式系统供应商(如Phar Lap)提供了自己的连接器,它们同时支持OMF和COFF,因此可供您选择。

底线是混合OMF和COFF对象和库文件类型可能是一团糟(加上来自连接器的神秘错误消息不起作用)。除非您的链接器专门支持它,否则您应该坚持为您的编译器/链接器/平台推荐的对象和库格式,并避免混合OMF和COFF文件。