我的问题是:究竟是什么使代码成为 16、32 或 64 位,是什么触发了 16 位应用程序显然存在的不兼容问题?
好吧:显而易见的答案是:取决于使用 8、16、32 或 64 位寄存器的程序。显而易见但不正确:如果处理器支持,在 MS DOS 中运行的程序可以使用 8,16 或 32 位寄存器。或者,除了使用 32 位寄存器和(如果处理器和操作系统支持)64 位寄存器之外,Windows 程序还可以使用(并且确实使用)8 位和 16 位寄存器。
我认为问题应该是:究竟是什么让程序能够在 DOS 或 Windows 32 位或 Windows 64 位下运行。
首先,可执行文件的结构。32 位或 64 位 Windows 可执行文件与 16 位可执行文件不同。Windows 使用所谓的“Portable Executable”(PE 的缩写)。MS DOS 使用 .COM 文件(继承自 CP/M)和 .EXE 文件(也称为 MZ 可执行文件)。
第二:程序存储在内存中并开始执行,程序期望存在一些环境,例如,由特殊指令(如 INT)访问的一组函数调用,它们负责执行不同的任务,从将字符输出到控制台,打开和读取文件等等。
第三:MS DOS 应用程序期望内存中的某些结构位于特定的内存地址;例如屏幕内存。它还期望某些 I/O 设备存在于特定的 I/O 地址。许多所谓的“不良行为”应用程序不使用 BIOS 或 DOS 在屏幕上打印,而是直接写入屏幕内存,以获得更快的输出。我记得 Turbo Pascal、Turbo Basic 或 Turbo C 编译器中的一个设置,让程序员选择控制台输出功能通过 BIOS,或直接进入硬件。
第四:程序期望处理器以特定方式运行。16 位 DOS 程序被设计为使用所谓的 x86 处理器实模式,并且这种模式强加了其对内存地址的特定视觉,这是该模式最显着的特征。随着将处理器置于保护模式的 32 位操作系统的到来,实模式程序无法工作,因为内存地址在保护模式下的工作方式与实模式下的工作方式非常不同。
愿意运行 MZ 可执行文件的操作系统需要某种类型的文件加载器(以符合第一点)和必须模仿应用程序应该工作的环境(以符合其余点)。在 Linux 世界中,这些组件是他们所谓的个性的一部分(Linux 运行来自其他操作系统(如 FreeBSD)的代码的一种方式,前提是该代码适用于两个平台上的相同处理器)。在 Windows 世界中,这称为子系统。例如,Windows XP 和 Windows 7 具有Win32子系统和DOS子系统。古代版本的 Windows(可能是 Windows NT 3.5 或 NT 4.0)有一个OS/2个性太强,能够运行 OS/2 16 位文本模式应用程序。
因此,您的 Windows 操作系统需要适当的子系统来运行为其他操作系统(如 MS DOS)设计的代码。但是处理器必须以任何可能的方式提供帮助。这是因为 x86 平台在 80386 中引入了8086 虚拟模式:能够创建一个任务,其中处理器的行为很像 8086 实模式。
因此,在 CPU 本身的帮助下,适当的加载程序,一个能够将 DOS 请求转换为 Windows 请求的 INT 处理程序,一个能够捕获对特定内存部分的访问并将其转换为在屏幕上绘制字符的请求的智能页面处理程序,和一个 I/O 故障处理程序,能够模拟应用程序使用的设备,为 DOS 编写的程序可以在 Windows 或 Linux (DOSemu) 下运行
那么,64 位会发生什么?对于能够访问 64 位寄存器的代码,使用了另一种保护模式,称为长模式。我对这种长模式了解不多,但从我阅读的内容来看,这种模式不允许处理器使用 8086 虚拟模式创建任务。还有另一种称为兼容模式或类似模式的模式,它允许处理器创建 64 位和 32 位任务,但不能创建 8086 虚拟模式任务。
如果没有 CPU 帮助,DOS 子系统很难实现:您可以模仿内存映射,捕获对特殊内存区域或 I/O 的任何访问,捕获 INT 指令,但除此之外,您应该捕获任何更新段寄存器的尝试为了尝试模仿实模式寻址,我实际上不确定段是否在长模式下使用。这是可行的,像 DOSBox 这样的应用程序证明了这一点,但微软不再需要 DOS(它已经很长时间不需要它了,但是客户可能直到 Windows 2000/XP 的推出才分享他们的观点) . Windows 7 32 位可以使用与以前的 Windows 版本相同的 DOS 子系统(我什至前段时间读过关于将 OS/2 子系统带回 Windows 2000 或 Windows XP 的黑客攻击),但对于 Windows 7 64 位,
更多信息:http:
//www.codeproject.com/Articles/45788/The-Real-Protected-Long-mode-assembly-tutorial-for#Main