COM 文件中使用了哪些指令集?我以为是8086,但似乎我错了。在我发现的 8086 手册中, shl 只能接受 1 或 cl 作为其第二个参数,而 1 以外的立即值对我来说可以正常工作。万一这很重要,我正在使用 NASM。
谢谢你的时间。
3 回答
这是那些有趣的问题之一,而且答案总是具有误导性。
真正的 DOS COM 文件没有标头,并且必须适合单个内存段,因为它没有重定位信息,DOS 必须将文件放在需要的位置,因此唯一真正兼容的方式(与 x86 兼容)是使用 8086 兼容程序集。编辑:为了澄清上述内容,这是因为 8086 没有内存页。
您当然可以在 286/386 操作数中进行编译,因为一旦程序运行,DOS 中就没有执行运行时来阻止您并说“不,您不能这样做,这是 386 指令”。
有趣的是,这也是 COM 文件在 Windows7 x32 中不经常工作或在 Windows7 x64 中根本不工作的部分原因。
由于 DOS 的工作方式,command.com 在您执行 .com 文件时被卸载,然后重新加载,所以本质上您的 .com 文件可以访问系统的所有内存,理论上使用 DOS 内存扩展器,如 Phar lap 的 DOS/4GW和 CWSDPMI 浮现在脑海中。
长话短说; 您可以使用当前系统可以支持的任何类型的命令,但您应该确保只使用 16 位 x86 兼容的命令。
如果上面听起来像 PITA,那是因为它是,我记得 :) 这也是 .EXE 格式迅速流行的原因。
真正的 COM(我不会涉及实际上是 EXE 等的 COM)只是意味着它是一个简单的 DOS 可执行文件。任何支持的指令集都是可用的。我过去曾经在 8088 到 i486 上进行 DOS 编程(COM 和 EXE),在那种模式下任何指令都是合法的,你可以使用。例如,当我的目标是“16 位”(技术上应该称为“实模式”)DOS 时,我经常使用 32 位字符串指令和立即推送。
COM 文件有两种主要类型。一种设计用于在 MS-DOS 中运行,另一种设计用于在 CP/M OS 中运行。据我所知,DOS COM 文件应该是基于 x86 的。根据维基百科,CP/M COM 文件可能是 8085、8080 或 Z80 指令。正如另一个答案提到的,COM 只是一种简单的可执行格式,可以使用任何受支持的底层指令集。
就 SHL 指令而言,现代 x86 硬件(可能是 x64)似乎支持对该指令使用立即值。但是,仅查看 8086 文档时,我找不到对它的引用,所以它一定是在某个时候添加的。以下是一些参考资料,其中详细介绍了此说明:
http://siyobik.info/main/reference/instruction/SAL%2FSAR%2FSHL%2FSHR