COM格式文件是一种简单的
可执行文件。在迪吉多公司于20世纪70年代推出的
操作系统中,.COM被用做包含操作系统支持命令的
文本文件的拓展名(类似于Windows系统的.cmd文件)。随着引进CP/M的引进(微型计算机的操作系统),COM扩展相的文件改变为的可执行文件。该格式后来被结转到
MS-DOS。虽然MS-DOS中已有更常见的.exe文件格式的,紧凑的COM文件仍然保持活力,并在MS-DOS频繁使用。
MS-DOS二进制格式
COM格式是在CP/M和MS-DOS中使用的原始二进制可执行格式。它很简单因为 它没有标题(除CP/M 3文件外),并且不包含标准元数据,仅包含代码和数据。 这种简单性是一个代价:二进制文件的最大大小为65,280(FF00h)字节(256字节短于64 KB),并将其所有代码和数据存储在一个段中。
由于它没有重定位信息,它被操作系统装载到一个预置地址,在PSP后面的偏移量0100h,它被执行(因此限制了可执行文件的大小):入口点固定为0100h。 这在8位机器上不是问题,因为它们可以最大地处理64k的内存,但是16位机器具有更大的地址空间,这就是为什么格式不再使用的原因。
在Intel 8080 CPU架构中,只能寻址65,536字节的内存(地址范围为0000h至FFFFh)。 在CP/M下,该存储器的前256字节(从0000h到00FFh)被保留供系统零页使用,并且任何用户程序都必须在0100h加载才能执行。 COM文件完全适合这个模型。 在引入MP / M和并行CP / M之前,一次不可能运行多个程序或命令:在0100h加载的程序运行,没有其他运行。
虽然MS-DOS和CP/M中的文件格式相同,但两个操作系统的.COM文件不兼容; MS-DOS COM文件包含x86指令和可能的MS-DOS系统调用,而CP/M COM文件包含8080指令(限于某些机器的程序也可能包含8085或Z80的附加指令)和
CP/M系统调用。
DOS中的.COM文件将所有x86段寄存器设置为相同的值,并将SP(堆栈指针)寄存器设置为FFFEh,因此堆栈从内存段的最顶端开始并从那里开始工作。
原来的DOS 1.x API是CP / M API的衍生产品,通过调用INT 20h(终止程序)函数或INT 21h函数0来执行程序终止.COM文件,他们起着同样的作用,程序员还必须确保程序终止时代码和数据段寄存器包含相同的值,以避免潜在的系统崩溃。 虽然这可以在任何DOS版本中使用,但是Microsoft建议使用INT 21h函数4Ch来从DOS 2.x以后的程序终止,它不需要将数据和代码段设置为相同的值。
可以在两个操作系统下运行.COM文件。 在指令级没有真正的兼容性; 入口点的指令被选择为在功能上相同但在两个操作系统中不同,并且使程序执行跳转到正在使用的操作系统的部分。 它基本上是两个不同的程序,在单个文件中具有相同的功能,之前是代码选择要使用的程序。
在CP/M 3下,如果COM文件的第一个字节是C9h,则有一个256字节的标题; 由于C9h对应于8080指令RET,这意味着如果在不支持该扩展的早期版本的CP/M上运行,COM文件将立即终止。(因为8085和Z80的指令集是8080指令集的超集,所以这三个处理器都可以工作。)C9h是8088/8086上的一个无效操作码,它会在v86模式下引发INT 6异常,因为386.由于C9h是自80188/80186以来的LEAVE操作码,因此不被用作有效程序中的第一条指令,因此某些版本的DOS中的可执行加载程序拒绝以C9h开头的COM文件,从而避免崩溃。
文件的名称可能以.COM结尾,但不能采用上述简单格式。 这由文件开头的幻数表示。 例如,DR DOS 6.0中的COMMAND.COM文件实际上是DOS可执行格式,前两个字节表示为MZ(4Dh 5Ah),即Mark Zbikowski的缩写。
在MS-DOS和兼容DOS中,加载器或执行环境没有为COM文件提供内存管理。所有内存都可用于COM文件。执行后,操作系统命令外壳COMMAND.COM将重新加载。这留下了COM文件可能非常简单,使用单个段或任意复杂的可能性,从而提供自己的内存管理系统。一个复杂程序的例子是COMMAND.COM,MS-DOS shell,它提供了一个加载器来加载其他COM或EXE程序。在.COM系统中,可以加载和运行较大的程序(最大可用内存大小),但系统加载程序假定所有代码和数据都在第一段中,并且由.COM程序提供任何代码和数据。进一步组织。如果必要的代码包含在.COM程序中,则可通过动态链接处理大于可用内存或大型数据段的程序。使用.COM而不是.EXE格式的优点是二进制图像通常更小,更容易使用汇编程序进行编程。一旦有足够功率的编译器和链接器可用,将.COM格式用于复杂程序就不再有利。
.COM文件在IBM PC早期之后通常不用于商业软件可执行文件,格式主要用于命令行应用程序。
支持平台
该格式在许多现代基于Windows NT的平台上仍然可执行,但它在MS-DOS仿真子系统NTVDM中运行,并不存在于64位变体中。 COM文件也可以在DOS模拟器(如DOSBox)上执行,在这些模拟器支持的任何平台上。
兼容性
基于Windows NT的操作系统使用.com扩展名来处理从MS-DOS时间传输的少量命令,尽管它们实际上当前实现为.exe文件。 操作系统将识别.exe文件头并正确执行它们,尽管它们在技术上不正确的.com扩展名。 (事实上,任何.exe文件都可以重命名.com并且仍然可以正确执行。)对这些命令使用原始.com扩展可确保与旧的MS-DOS批处理文件兼容,这些文件可能使用完整的原始文件名引用它们。 这些命令是chcp.com,discomp.com,diskcopy.com,format.com,mode.com,more.com和tree.com。
执行效果
在MS-DOS中,如果一个目录同时包含一个COM文件和一个具有相同名称的EXE文件,那么当没有指定扩展名时,将优先选择COM文件进行执行。 例如,如果系统路径中的某个目录包含两个名为foo.com和foo.exe的文件,则以下命令将执行foo.com:
运行foo.exe的用户可以显式使用完整的文件名:
利用这种默认行为,病毒编写者和其他恶意程序员使用notepad.com这样的名字来创建它们,希望如果将它放在与相应的EXE文件相同的目录中,命令或批处理文件可能会意外触发它们的程序 而不是文本编辑器notepad.exe。 再次,这些.com文件实际上可能包含一个.exe格式的可执行文件。
在Windows NT及衍生产品(Windows 2000,Windows XP,Windows Vista和Windows 7)上,PATHEXT变量用于覆盖调用文件的首选项(以及可接受的扩展名)的顺序,而无需在命令行中指定扩展名。 默认值仍然在.exe文件之前放置.com文件。 这与以前在JP Software的扩展命令行处理器4DOS,4OS2和4NT系列中发现的功能非常相似。
恶意使用.com
一些计算机病毒作者希望利用现代计算机用户可能缺乏对.com文件扩展名和相关二进制格式的知识,以及他们更可能熟悉.com
互联网域名。 电子邮件已发送附件名称类似于“www.example.com”。 不小心的微软Windows用户点击这样的附件可能会开始浏览一个名为http://www.example.com/的网站,而是运行附件的二进制命令文件www.example,并给予它完全的权限 无论其作者想到的是什么机器。
注意COM文件格式本身没有任何恶意; 这是对.com命令文件和.com商业网站之间巧合名称冲突的利用。