MZ

来自osdev
跳到导航 跳到搜索
可执行文件格式
Microsoft

16 bit:
COM
MZ
NE
32/64 bit:
PE
Mixed (16/32 bit):
LE

*nix

MS-DOS EXE格式,以MZ签名开头(微软工程师马克·兹比科夫斯基-Mark Zbykowski的首字母缩写),是在MS-DOS 2.0中引入的(1.0版仅采用简单的COM格式)。 它被设计成在实模式下运行的可重新定位的可执行文件。 因此,只有DOS和Windows 9x可以本机使用这种格式,但通过几个自由的DOS模拟器(例如DOSBox),可实现在各种操作系统(如Linux、Amiga、Windows NT等)下运行。 虽然MZ可执行文件可以独立存在,但它们嵌入在所有NELEPE可执行文件中,通常作为以上文件的存根,因此以上文件在DOS下运行时,它们会显示:

   This program cannot be run in MS-DOS mode.

所以也可以使用它们,以便单个可执行文件可以为同一应用程序提供两个入口(例如,一个用于DOS,一个用于Windows)。 如果从命令行提示符启动程序,Windows 9x将运行MZ可执行文件,如果正常启动,则运行PE可执行文件。 在引导加载程序(boot loaders)中,它们可以帮助提供一个DOS版本,尤其是因为UEFI需要PE格式,而其中刚好可以包含一个MZ可执行文件。

MZ文件结构

MZ可执行文件仅由两个结构组成:文件头和重定位表(relocation table)。 文件头后面是程序映像,文件头如下所示:

偏移量 字段 大小 描述
0 0x00 签名(Signature) word 0x5A4D(ASCII表示“M”和“Z”)
2 0x02 Extra bytes word 最后一页中的字节数。
4 0x04 Pages word 所有页的数量。
6 0x06 Relocation items word 重新定位表中的条目数。
8 0x08 Header size word 文件头占用的段落数。 其实它可以是任何值,因为加载程序只使用它来查找实际可执行数据的起始位置。 它可能比“标准”字段的头文件占用的空间大,这样如果您想包含自己的文件头元数据,甚至将重定位表放在那里,或者将其用于任何其他目的,都可以使用标准头以后的空间。
10 0x0A Minimum allocation word 程序必要的段落数,不包括PSP和程序映像。(译者注:PSP指Program Segment Prefix) 如果没有足够大的自由块,加载将停止。
12 0x0C Maximum allocation word 程序请求的段落数。 如果没有足够大的空闲块,则分配最大的空闲块。
14 0x0E Initial SS word SS的可重定位段地址。
16 0x10 Initial SP word SP的初始值。
18 0x12 校验和(Checksum) word 当和文件中所有其他word求和时,结果应为零。
20 0x14 Initial IP word IP的初始值。
22 0x16 Initial CS word CS的可重定位段地址。
24 0x18 Relocation table word 到重定位表的(绝对)偏移量。
26 0x1A Overlay word 用于Overlay管理的值。如果为零,则这是主可执行文件。
28 0x1C Overlay information N/A 文件有时包含用于主程序Overlay管理的额外信息。

段落大小为16字节。页面(或块)的长度为512字节。

如果minimum 和 maximum allocation字段都清除了,MS-DOS将尝试在内存中尽可能高地加载可执行文件。 否则,在内存不足时,映像将加载到256字节PSP结构的正上方。

重定位

在将可执行文件加载到内存中之后,程序加载器将遍历重定位表中的每个条目。 对于每个重定位条目,加载器将起始段地址添加到segment:offset对指向的字值中。 因此,例如,重新定位条目0001:001A将使加载程序将起始段地址添加到程序数据中偏移量1*0x10+0x1A=0x2A处的值。

重定位表中的每个指针如下所示:

偏移量 字段 大小 描述
0 0x00 Offset word 在提供的区段内重新安置的偏移量。
2 0x02 Segment word 相对于加载段地址的重新定位段。

CS和SS寄存器以类似的方式重新定位。

初始程序状态

  • ES和DS寄存器都指向包含PSP结构的段。
  • CS等于文件头中指定的值,通过向其添加起始段地址重新定位。
  • IP等于文件头中指定的值。请注意,与COM可执行文件不同,MZ程序不会在偏移量0x100处启动。
  • SS等于文件头中指定的值,重新定位,就像CS一样。
  • SP等于文件头中指定的值。
  • 如果PSP中的第一个FCB具有有效的驱动器标识符,则AL为0x00,否则为0xFF。
  • AH与AL相同,但适用于PSP中的第二个FCB。
  • 所有其他寄存器可以设置为0,也可以不设置为0。你应该认为它们都还没有定义。

PE扩展

随着PE可执行文件的出现,微软在MZ头文件中添加了一些项目,在WinNT.h中进行了定义

偏移量 字段 大小 描述
28 0x1C Reserved qword
36 0x24 OEM identifier word 按名称定义,但未提供其他信息;通常为零
38 0x26 OEM info word 按名称定义,但未提供其他信息;通常为零
40 0x28 Reserved 20 bytes
60 0x3C PE header start dword PE头的起始地址

另见