为什么 64 位操作系统不能运行 16 位应用程序?

41 windows windows-7 64-bit 16-bit

为什么是这样:

  • 32 位操作系统,当安装在 64 位 CPU 上时,可以运行旧的 16 位应用程序,
  • 但是如果你安装了一个 64 位的操作系统,它就不能直接运行那些应用程序并且需要某种模拟(这并不总是完美地工作)?

更具体地说,我有一个 64 位处理器(Intel Core 2 Duo)。当我安装了 Windows XP 和 Windows 7(均为 32 位)时,它们可以运行旧的 DOS 和 616 位 Windows 应用程序。

现在我已经安装了 64 位版本的 Windows 7。为什么它不能运行那些相同的应用程序了?

Mat*_*ker 28

据我了解,这是因为在 Long Mode(x64 native)下运行时,CPU 本身不支持进入 16 位模式。参见维基百科。因此,为了支持 16 位模式,NTVDM(Windows 中的 16 位层)必须完全模拟 16 位处理器。

我想他们权衡了重新实现仿真层与使用已经存在的虚拟化软件(VirtualPC、VirtualBox)来处理这个问题,并决定削减 VDM。

  • 引自 [维基百科](http://en.wikipedia.org/wiki/NTVDM):*64 位架构(x64 和 IA-64)的 Windows NT 版本不包括 NTVDM,并且无法运行 DOS 或16 位 Windows 应用程序。这是因为,在 x86-64 CPU 中,虚拟 8086 模式仅在其传统模式(用于运行 16 位和 32 位操作系统)中作为子模式可用,而不是在本机 64 位长模式下;需要对 CPU 进行硬重置才能切换到传统模式。* 因此,到目前为止 NTVDM 的唯一工作方式不再可用,并且有大量完整的 VM,因此 NTVDM 被切断了。 (7认同)
  • 哎呀,我不敢相信他们放弃了 V86 模式。如果您打算这样做,不妨完全放弃实模式并要求 32/64 位引导加载程序。 (5认同)
  • 这正是已经发生的事情,M. Knoblauch。[带有 EFI 固件的现代 x86 机器在其前几条指令中直接从虚幻模式进入 64/32 位保护模式。](http://superuser.com/a/345333/38062) 引导加载程序确实是 64/ 32 位保护模式程序。这就是 EFI 启动应用程序。在过程中的任何地方都没有使用实模式或 v8086 保护模式。 (5认同)
  • @HughAllen:该页面当前显示“当前 64 位版本的 linux 内核缺乏对 V86 模式的支持,因为这些处理器的本机操作模式(长模式)不支持它。” 和“这个补丁是*非常实验性的*。” 简短的回答是,虽然*可能*运行 16 位代码,但通过完全退出长模式,这样做并不*明智*。 (4认同)
  • -1. WINE 支持在 64 位 Linux 上以 VM86 模式运行 16 位 Windows 应用程序。[屏幕截图](http://en.wikipedia.org/wiki/File:Wineon64bit.png)。[V86-64 项目页面](http://v86-64.sourceforge.net/)。Mehrdad 的回答似乎是更令人信服的理由。 (3认同)
  • 这个答案和评论混淆了虚拟 8086 模式(又名 DOS)和 16 位保护模式(又名 win16)。前者在长模式下不可访问,后者可以(并且由 wine 使用) (2认同)

use*_*686 16

因为64 位句柄有 32 个有效位

请注意,64 位 Windows 不支持运行 16 位基于 Windows 的应用程序。
主要原因是句柄在 64 位 Windows 上有 32 个有效位。
因此,句柄不能被截断并传递给 16 位应用程序而不会丢失数据。

在 Windows 中,程序将“句柄”传递给操作系统,反之亦然(操作系统使用这些数字来唯一标识特定资源,例如窗口)。

为了支持 16 位程序,32 位 Windows生成具有 16 位有效位的句柄——操作系统忽略高 16 位(即使程序不会利用这一事实)。所以没有一个程序可以与超过 2 16 个对象进行交互,这实际上是相当低的。

但是,为了改进这一点,64 位 Windows 将句柄中的有效位数量增加到 32。但是现在这意味着句柄不能在不丢失信息的情况下传递给 16 位程序。因此 16 位程序无法在 64 位 Windows 上运行。

  • @Joey:我不明白你在说什么。如果操作系统是 64 位 Windows,那么 16 位应用程序就不能在它上面运行了。我看不出它们是“DOS”或“Windows”应用程序这一事实如何改变这里的任何内容——无论哪种方式,句柄都需要被应用程序截断。 (3认同)
  • DOS 应用程序没有句柄。事实上,他们(通常)甚至不知道自己正在 Windows 上运行。 (2认同)
  • ...实际上,即使是Win16代码也不应该有太大问题,现在想想。您所需要的只是一个查找表。 (2认同)

Sql*_*yan 11

对于 Windows,这是因为 x86 版本的操作系统包括 16 位仿真,允许它们运行那些较旧的 DOS 进程。在 x64 版本中,他们已经不得不模拟 x86 执行(他们称之为 WoW64)以允许 32 位进程运行,我猜使用 Wow64 进一步模拟 16 位模拟器造成了太多问题。

少数可识别的 16 位进程将运行,因为模拟是硬编码来处理它们的,但其余的将不起作用,因为 x64 中不包含模拟。

请参阅 MSKB 文章中的“无 16 位代码”:http : //support.microsoft.com/kb/282423

  • 没有进行模拟 - x86/64 可以本机运行这些东西。然而,API thunking 正在进行中。Microsoft 选择了这个机会来淘汰一项非常陈旧且几乎未使用的技术。 (14认同)

plu*_*ash 6

Dos 应用程序和 16 位 Windows 应用程序的情况有所不同。

对于 Dos 应用程序,问题在于虚拟 8086 模式在长模式下不可用。这是 CPU 架构的限制。

对于 16 位 Windows 应用程序(在 16 位保护模式下运行),原因是 MS 没有准备好实施合适的兼容层。Amusingly Wine 完全能够在 64 位 Linux 上运行 16 位 Windows 应用程序。

  • 据我了解,兼容模式允许 16 位保护模式,但不允许虚拟 8086 模式。 (2认同)