可执行文件在计算机科学上,指一种内容可被电脑解释为程序的电脑文件。通常可执行文件内,含有以
二进制编码的微处理器指令,也因此可执行文件有时称为
二进制档。
这些二进制微处理器指令的编码,于各种微处理器有所不同,故此可执行文件多数要分开不同的微处理版本。一个电脑文件是否为可执行文件,主要由操作系统的传统决定。例如根据特定的命名方法(如扩展名为exe)或文件的元数据信息(例如
UNIX系统设置“可运行”权限)。
除了
微处理器指令,可执行文件也具有
系统调用数据,让程序可使用操作系统提供的服务。因为系统调用数据,在各操作系统都有所不同,因此可执行文件除多数要分开不同的微处理版本,也有分开不同操作系统版本。
不是所有的
可执行文件,都只存有电脑能阅读的数据。以
脚本语言撰写的
脚本文件,都可以是可执行文件,而且内含的数据可被人类阅读,多数以
ASCII文本存盘。原因是:脚本语言无需经过
编译器预先编译,就可经过
解释器(如
Perl、
Python、Shell)运行。
DOS可执行文件中的内容是由
源程序中所写的
代码和数据定义转换而来的。惟一的例外是带覆盖部分(Overlay)的exe文件,它在基本的exe文件后附加了一些自定义的数据,其中可执行部分的长度由
文件头偏移0002h和0004h中的长度给出,该长度之后到文件实际长度这部分就是Overlay部分。这样,即使一个带覆盖的exe文件大小远远超过640 KB,在DOS下也能运行,因为
操作系统只装入真正的可执行部分,然后由
程序自己去读取覆盖部分的数据。一些打包
软件生成的奇大无比的自解压包就采用这种结构,可执行部分是
解包代码,覆盖部分是被压缩的数据。DOS对可执行文件覆盖部分的数据格式并没有规定,它是程序员按自己的方式组织的。如果程序员愿意,也可以把这些数据单独放在另外一个文件中。
Win32可执行文件叫做PE文件。PE文件的基本结构和DOS可执行文件有很大的不同。它把
程序中的不同部分分成各种
节区(Section),其中可以有一个节区是放置各种资源的,如菜单、对话框、
位图、
光标、图标和声音等。虽然可以把资源部分理解成类似DOS可执行文件中的“覆盖”部分,但由于资源是Win32可执行文件的标准组成部分,而且是非常重要的组成部分,它的格式是固定的。所以与DOS
软件的开发
过程相比,Win32软件的开发中多了一个创建
资源文件的步骤。
以使用MASM32
软件包为例,在用Win32汇编开发软件的流程中,程序员要做的工作分创建
代码和创建资源两部分。
代码部分的开发工作与DOS下写代码的步骤是一样的。程序员用
文本编辑器书写汇编
源代码(*.asm文件)。与C
源代码类似,asm文件中也可以用include语句包含数据定义和函数声明的头文件,Win32汇编的头文件一般用inc作扩展名。大部分的include文件是
编译器软件包附带提供的,如MASM32软件包附带的Windows.inc文件定义了Win32 API中很多参数和
数据结构,其他的inc文件则是不同DLL中的Win32
API函数声明。最后,asm文件经汇编
编译器编译成以obj为扩展名的目标文件。
资源文件中可以包括对话框、
快捷键、
菜单、字符串、版本信息和一些图形资源等内容。
资源文件的源文件是一种类似“
脚本”的文本文件,它的扩展名一般为rc,其中用不同的
语法定义了不同类型的资源,资源
脚本文件最后由资源
编译器编译成资源文件*.res。资源
脚本文件同样用到很多预定义值,所以
软件包中一般也包括资源头文件供源文件来导入。MASM32
软件包中的资源头文件是Resource.h。
在
资源文件中,不同类型资源的记录方式是不同的。对话框资源只记录定义值,如对话框的大小、位置等,并非真正存储对话框最后显示在
屏幕上的像素。这些大小、位置等信息最后由Windows解释后才在
屏幕上被绘画成像素;
菜单、字符串、
快捷键等由
文本构成;图形资源则真正由像素组成,它们在资源
脚本中被定义为一个文件名,由资源
编译器从磁盘文件导入。Windows在资源中支持的图形文件有bmp
位图文件、cur光标文件和ico
图标文件,这些图形文件可以用其他图形处理
软件生成。另外,wav声音文件也可以用在资源中。创建资源的方法在第5章中有详细的描述。
编译好
目标文件*.obj和
资源文件*.res后,最后一步是用
链接器将它们链接成可执行文件。链接的时候要用到函数库。在DOS环境下
编程的时候,使用的函数库是
静态库。
静态库是一些已经编译好的
代码模块。当用户在
源程序中用到某个函数的时候,
链接器从库文件中将这个函数的
二进制代码取出,与obj文件合在一起生成最终的exe文件。但在Win32环境下,大部分的公用
函数封装在
DLL文件中,以
动态链接的方式供
用户程序调用。这时候库文件中只需要包含函数在DLL中的位置信息,不再需要有
二进制代码部分。所以链接的时候也只是把库文件中的位置信息取出放入最后的可执行文件中。Win32中这种只包含位置信息的库文件称为
导入库。