DOS标头中的e_cblp和e_cp是什么?

ali*_*ali 5 executable exe header dos portable-executable

我正在尝试深入理解DOS标题,我坚持使用这些标题.我知道唯一需要的字节是MZ签名和指向PE部分的指针,但我必须知道这两个是什么:

USHORT e_cblp;          // Bytes on last page of file
USHORT e_cp;            // Pages in file
Run Code Online (Sandbox Code Playgroud)

在大多数可执行文件的二进制代码中,这些值分别为90h和03h.一个页面是512字节的代码,所以有3个页面,但在哪里?我在哪里可以找到它们?如何在512字节的最后一页中识别这些90h(144)字节?

此信息仅由DOS请求.将在DOS中运行的PE文件的唯一代码是DOS存根,它不是3页代码而只是64字节.那么,90h和03h必须做什么?我不能只说e_cblp=01he_cp=DOS header+DOS stub

Ros*_*dge 1

它是“整个”MZ 格式可执行文件的大小,最后一页中最后一个字节之后的任何内容都将被忽略。当 MS-DOS 加载 MZ 格式的可执行文件时,它会复制文件中标头之后的所有内容,直到达到此限制。因此,大多数 PECOFF 可执行文件将此字段设置为大于 MS-DOS 存根的值,这意味着当可执行文件在 MS-DOS 下运行时,PECOFF 标头和部分 PECOFF 节数据将被加载到内存中。

我不知道为什么 Microsoft 链接器(和 GNU 链接器,但不是 Borland 或 Watcom 的)使用的默认 DOS 存根说它的大小为 1168 字节,而实际上要小得多。如果您在使用 Microsoft 的链接器时提供自己的存根,它将使用所提供的可执行文件的大小。Windows 在加载 PECOFF 可执行文件时似乎会忽略此值,并且默认的 DOS 存根对额外数据没有任何用处。

请注意,可以使用 Microsoft 的链接器创建仅 1024 字节长的有效 PECOFF 可执行文件。这要求可执行文件只有一个部分,并且大小小于 512 字节。虽然 Windows 将加载并运行可执行文件,但 MS-DOS 将拒绝加载并运行,因为文件大小小于 MZ 标头中给出的 1168 大小值。