DOS头文件中的e_cblp和e_cp是什么?



我试图深入了解DOS头,我被这些困住了。我知道唯一需要的字节是MZ签名和指向PE部分的指针,但我必须知道这两个究竟是什么:

USHORT e_cblp;          // Bytes on last page of file
USHORT e_cp;            // Pages in file

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

此信息仅由DOS请求。一个PE文件的唯一代码,将在DOS中运行,是DOS存根,它不是3页的代码,但只有64字节。那么90h和03h有什么关系呢?我就不能说e_cblp=01he_cp=DOS header+DOS stub吗?

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

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

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

e_cblp:

指定最后一页实际使用的字节数,特殊情况下,整页用值0表示(因为最后一页从不为空)。例如,假设页面大小为512字节,对于1024字节的文件,该值为0x0000,对于1025字节的文件,该值为0x0001(因为它只包含一个有效字节)。

所以,1024 + 144(90h) = 1168字节

最新更新