创建多种文件格式有什么用?

时间:2016-05-24 13:31:33

标签: assembly operating-system kernel portable-executable coff

我正在学习操作系统概念。我自己设法创建了一个启动加载程序。 我生成的每个可执行文件都在BIN中。 我看到微软为其系统使用了PE文件格式。同样Unix使用COFF。 这些多种文件格式有什么用?与其他相比,它们是否具有任何文件保护或附加功能?

2 个答案:

答案 0 :(得分:6)

从历史上看,目前使用的常见目标文件格式PECOFFELFMach-O是针对特定操作系统完全独立开发的(Windows NT,Unix System V R4和Mach)并且旨在解决先前目标文件格式的缺点。

的Unix

的a.out

Unix使用的最早的目标文件和可执行格式是a.out格式。这是一种非常简单的格式,几乎是当时硬件所需的最低限度。它的名称取决于Unix汇编程序和链接器使用的默认输出文件名。如果未指定输出文件,则这些程序将创建名为a.out的文件。今天大多数Unix汇编程序和链接器仍然这样做。

COFF

使用Unix System V,AT& T引入COFF(通用目标文件格式)来替换a.out格式。它也是一种可执行文件和目标文件格式。它改进了a.out格式的主要内容是多个部分。 a.out格式仅支持带有隐含.bss部分的文本和数据部分。多个部分为工具和应用程序提供了布局可执行文件的更大灵活性,允许它们创建例如只读数据部分。 COFF还增加了对共享库的支持。

ELF

为了解决COFF的许多问题,AT& T为Unix System V R4创建了ELF(可执行和可链接格式)。 COFF的主要问题是,它不是非常灵活且定义明确,因此必须由各种实施的供应商以各种不兼容的方式进行扩展。它不是" Common"希望格式化。 ELF还为位置无关的共享对象提供支持,其具有比COFF共享库更动态的符号链接形式。它还具有相当复杂且可扩展的关联调试格式,称为DWARF

在Unix机器上,ELF是主要的可执行文件和目标文件格式。只有少数像AIX这样的操作系统坚持使用他们自定义的基于COFF的格式。所有大型开源操作系统,Linux和BSD都使用ELF,但值得注意的是,他们直接从基于a.out的格式转到ELF,跳过了COFF。由于ELF是一种目标文件格式和可执行格式,这意味着大多数Unix开发工具都会创建链接在一起的ELF对象来创建ELF可执行文件。

微软

OMF,.COM和MZ .EXE

在MS-DOS下,标准目标文件格式为英特尔为其x86处理器创建的OMF(对象模块格式)。 MS-DOS本身使用了两种不同的可执行格式。起初它只支持简单的.COM文件,只是像引导程序一样的平面二进制文件,取自CP / M(就像MS-DOS 1.x中的几乎所有东西一样)。使用MS-DOS 2.0,Microsoft添加了对"MZ" .EXE可执行文件的支持,因为它使用两个字符MZ作为幻数来标识文件类型。 MZ格式允许可执行文件使用多个段,而.COM格式有效地将程序限制为单个64K段。 Microsoft自己的MS-DOS开发工具以及大多数其他第三方工具生成了OMF格式的目标文件,这些文件被链接以创建.COM和MZ格式的可执行文件。

新的可执行文件(LE)

对于Windows 1.0,Microsoft为Windows可执行文件创建了New Executable(NE)格式。这种格式的关键特征是它在可执行文件中显示了段,显示了它们的起始位置和结束位置。 MZ格式通过重新定位代码中的段值来支持段。否则它是一个平面二进制文件,在一个连续的块中加载到内存中,就像.COM文件一样,除了段引用被修复了。在可执行文件中显式显示段允许Windows单独加载段,甚至可能移动它们并根据需要卸载它们。由于Windows与MS-DOS不同,支持一次运行多个程序,因此这非常重要,否则内存很快就会变得过于分散。 NE格式添加的另一个重要功能是支持DLL(动态链接库)。

但是Microsoft并没有改变使用的目标文件格式。用于早期16位版本Windows的Microsoft开发工具(以及16位版本的OS / 2)继续创建链接以创建NE格式可执行文件的OMF目标文件。 OMF格式易于扩展,并且NE格式仅需要少量添加,最明显的是用于导入和导出DLL的符号。

线性可执行文件(LE)

对于Windows / 386 2.10,Microsoft创建了另一种名为Linear Executable(LE)的可执行格式。这个新版本的Windows有一个32位的虚拟机管理器(VMM),本质上是一个简单的虚拟机,可以并行运行Windows和一个或多个MS-DOS实例。对于每个操作系统来说,看起来他们自己拥有整个PC,但实际上它只是一个虚拟机。自从 VMM,更重要的是它的驱动程序(VxDs)是32位,它们旧的16位NE格式不起作用。

我不确定最初创建LE可执行文件时使用的对象格式。之后,在创建VxDs时使用PECOFF目标文件成为标准,但直到几年后才创建该格式。他们可能使用OMF,扩展为支持32位对象,就像IBM对OS / 2 2.0所做的那样,它也为其32位可执行文件使用了LE格式的变体。

PECOFF

Microsoft在Windows NT中引入了PECOFF。虽然它们已经是可用的32位可执行格式,LE格式和OMF支持的32位对象,但这两种格式都与英特尔x86处理器相关联。 Windows NT旨在支持多种CPU,最初它支持MIPS和DEC Alpha CPU以及基于x86 Intel的PC。开发Windows NT的团队决定调整已支持多个CPU的现有Unix COFF格式,而不是让LE和OMF适应这些其他处理器。我的猜测是,早期的Microsoft Windows NT团队使用现有的基于Unix的开发工具来开发Windows NT,而不是等待Microsoft的独立开发工具团队为其他CPU创建工具。否则Windows NT可能会有LE和OMF格式的改编版本,只是为了让开发工具团队的工作变得更容易。

PECOFF在COFF上添加的主要功能是对DLL的支持,这是Windows从一开始就固有的东西。 COFF支持类似但不同的共享库机制。 Microsoft后来扩展了PECOFF格式以支持64位CPU。

由于PECOFF既是目标文件格式又是可执行文件,因此用于32位版本Windows的Microsoft开发工具会创建链接以创建PECOFF可执行文件的PECOFF目标文件。值得注意的是,Borland的工具生成了OMF文件,这些文件被链接以创建PECOFF可执行文件,但是现在大多数其他工具都遵循微软的主导(例如MinGW或Intel的ICC)。

OS X

的Mach-O

Mach-O格式是为Mach kernel创建的,因此是名称。这个内核在NeXTSTEP中使用,后者成为Apple OS X的基础.Mach-O格式是作为BSD使用的a.out格式的替代品而创建的,它提供了大多数基于Mach的非内核部分。操作系统。主要驱动力似乎是创建位置独立的共享库和可执行文件。 Mach-O和使用它的操作系统的一个特点是所有代码都需要与位置无关,而不仅仅是共享库。

结论

因此,您可以看到在不同操作系统上工作的不同人群已经独立工作,根据他们当时的需求创建这些不同的格式。早期微软需要格式来支持英特尔x86的特殊分段内存模型,而OMF是唯一支持它的目标文件格式。 Unix需要不同的东西,支持多个CPU。当Microsoft需要多个CPU支持时,他们选择将其格式基于最近废弃的COFF格式,当时这种格式可能是在比新的ELF格式更多的CPU类型上实现的。与此同时,Mach内核开发人员在他们自己的世界中离职,徒劳地试图创建一个可行的微内核。我不确定他们用Mach-O究竟在想什么,但是他们不得不用其他东西替换a.out而且我觉得COFF没有完成任务而且ELF还没有存在。

答案 1 :(得分:4)

除了独立团队之外,有多个object file formats可能会以不同方式解决同一问题。多年前,当每个计算机系统不同且不兼容,拥有专有操作系统,并且没有可用的开源代码时,目标文件格式标准化将没有任何用处。随着CP / M,Unix,MS-DOS,Linux和Windows等便携式操作系统的引入,相同类型的系统之间的标准化的一些要素变得必要,但没有必要在这些系统之间进行标准化。

请注意,Microsoft的可执行文件格式为PE,但PE中使用的目标文件格式为COFF。

使不同格式适合不同环境的目标代码格式的另一个方面是重新计时环境。加载到ROM的代码不需要元数据,因为它不是动态加载的,因为可能使用原始二进制文件或十六进制编码文件,类似位置相关的代码需要加载非常少的信息,但是由操作系统加载的用户应用程序代码包含使用的信息由操作系统的加载器在适当的运行时环境中加载和启动应用程序。不同的操作系统以不同的方式执行此过程,因此它们具有不同的可执行格式也许并不奇怪。