-----------------
│ Section ... │
-----------------
│n,Section n │
-----------------
记得在我还没有接确Win32编程时,我曾在Dos下运行过一个Win32可执行文件,程序只输出了一行"This program cannot be run in DOS mode.",我觉得很有意思,它是怎么识别自己不在Win32平台下的呢?其实它并没有进行识别,它可能简单到只输入这一行文字就退出了,可能源码就像下面的C程序这么简单:
#include <stdio.h>
void main(void)
{
printf("This program cannot be run in DOS mode.\n");
}
你可能会问"我在写Win32程序时并没有写过这样的语句啊?",其实这是由连接器(linker)为你构建的一个16位DOS程序,当在16位系统(DOS/Windows 3.x)下运行Win32程序时它才会被执行用来输出一串字符提示用户"这个程序不能在DOS模式下运行".
我们先来看看DOS MZ header到底是什么东西,下面是它在Winnt.h中的结构描述:
typedef struct _IMAGE_DOS_HEADER { //DOS .EXE header
WORD e_magic; //0x00 Magic number
WORD e_cblp; //0x02 Bytes on last page of file
WORD e_cp; //0x04 Pages in file
WORD e_crlc; //0x06 Relocations
WORD e_cparhdr; //0x08 Size of header in paragraphs
WORD e_minalloc; //0x0a Minimum extra paragraphs needed
WORD e_maxalloc; //0x0c Maximum extra paragraphs needed
WORD e_ss; //0x0e Initial (relative) SS value
WORD e_sp; //0x10 Initial SP value
WORD e_csum; //0x12 Checksum
WORD e_ip; //0x14 Initial IP value
WORD e_cs; //0x16 Initial (relative) CS value
WORD e_lfarlc; //0x18 File address of relocation table
WORD e_ovno; //0x1a Overlay number
WORD e_res[4]; //0x1c Reserved words
WORD e_oemid; //0x24 OEM identifier (for e_oeminfo)
WORD e_oeminfo; //0x26 OEM information; e_oemid specific
WORD e_res2[10]; //0x28 Reserved words
LONG e_lfanew; //0x3c File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
DOS MZ header中包括了一些16位DOS程序的初使化值如果IP(指令指针),cs(代码段寄存器),需要分配的内存大小,checksum(校验和
)等,当DOS准备为可执行文件建立进程时会读取其中的值来完成初使化工作.
留意到最后一个结构成员了吗?微软的人对它的描述是File address of new exe header意义是"新的exe文件头部地址",它是一个相对偏移值,我想文件偏移量你一定知道是