最近,我一直在维护用VC ++ 6.0编写的旧项目。该代码使用了此编译器的许多独特特性,以至于将其移植到最新的标准编译器已被证明是一项艰巨的任务。
在项目的数千行代码中,有四个汇编文件。由于某种原因,我不明白,尽管MASM615和TASM都无法编译它们(它们发送错误),但是我有目标文件。但是,当我链接库时,会收到一条消息
警告LNK4033:将对象格式从OMF转换为COFF
该库可以按预期工作,但是我一直想知道这些二进制格式之间有什么区别,或者我是否应该从这种转换中得到一些丑陋的印象。
最佳答案
答案因“ MetaWINDOW常见问题解答-OMF与COFF对象文件Formats.htm”而刻薄
自从PC文明诞生之日起直到大约Microsoft Win32编程工具问世,几乎所有PC编译器都使用Intel Object Module Format(OMF)标准来生成目标文件。后来,英特尔推出了386处理器和32位保护模式,这时他们还将OMF规范扩展为32位,从而使“ OMF-386”成为大多数PC保护模式环境的标准。大约在同一时间,最初的Windows NT开发团队也正在设计代码,不仅用于Intel处理器,而且还支持其他供应商的处理器。 Microsoft NT团队从UNIX System V的官方对象代码格式中选择了一种更具移植性的对象模块格式,称为通用对象文件格式(COFF)。COFF对象模块后来成为所有Microsoft Win32开发工具的事实上的标准,并且获得了格式与可移植可执行文件更加接近的一个优势-Win32的本机可执行文件格式(COFF格式链接器从COFF文件创建32位EXE或DLL的工作比从OMF格式文件少得多)。
就像有OMF和COFF格式的目标文件(.obj)一样,也有OMF和COFF格式的库文件(.lib)。幸运的是,这些库基本上只是对象文件的集合,还有一些头信息,这些信息使链接程序可以从库中确定要使用的对象文件。但是让事情变得困难的是,OMF和COFF都使用相同的文件扩展名.obj和.lib来引用两种不同类型的对象和库文件格式(因此,您不能只看文件扩展名判断目标模块或库文件是OMF还是COFF)。
将来自不同编译器供应商的目标文件和库文件混合在一起的问题是,一些供应商支持COFF,另一些供应商使用OMF,而少数供应商可以同时处理这两个问题。例如,Borland仍然使用OMF目标文件和库,而Microsoft的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文件。
关于visual-c++ - OMF和COFF格式有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/966597/