为什么64位OS无法运行16位应用程序?


38

为什么会这样:

  • 当32位操作系统安装在64位CPU上时,可以运行旧的16位应用程序,
  • 但是,如果您安装的是64位操作系统,则无法直接运行那些应用程序,并且需要某种模拟(并非总是能完美运行)?

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

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


3
我认为这与位无关,而与来宾操作系统有关。您具体指的是什么操作系统?
Pekka支持GoFundMonica 2010年

它将在DOSBox下运行吗?
企鹅

1
有一个名为DOSBOX的实用程序,它具有16位仿真器,可为您的16位程序提供虚拟的16位计算机进行工作,并且免费。

我同意Pekka的观点,事实是64位(硬件)系统可以运行16位代码(如果操作系统是这样设计的,那么甚至可以是1位代码)。真正的问题是,由于指针大小不同等原因,CPU无法直接运行16位代码,但是这些问题可以由OS加以抽象。该限制是Microsoft为简化操作而施加的一种人为限制(尽管它们仍然模拟32位,因为仍然有太多的32位代码)。还有其他操作系统(* nix?)可以运行16位代码而不会出现问题。
Synetech

您将Windows与所有操作系统混淆了。
肯·夏普

Answers:


24

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

我想他们权衡了重新实现仿真层与使用现成的虚拟化软件(VirtualPC,VirtualBox)来解决这个问题的决心,因此决定削减VDM。


6
引自维基百科64位体系结构的Windows NT版本(x64和IA-64)不包括NTVDM,并且不能运行DOS或16位Windows应用程序。这是因为,在x86-64 CPU中,虚拟8086模式仅在其传统模式(用于运行16位和32位操作系统)下才可作为子模式使用,而在本机64位长模式下则不可用。要切换到传统模式,需要对CPU进行硬复位。因此,到目前为止,NTVDM运作的唯一方式不再可用,并且完整的VM数量很多,因此NTVDM被削减了。
乔伊(Joey)

5
uck,我无法相信他们放弃了V86模式。如果您要这样做,还可能会完全抛弃实模式,并需要32/64位引导加载程序。
Brian Knoblauch

5
诺布拉赫先生,这正是已经发生的事情。 带有EFI固件的现代x86机器从其最初的一些说明中的虚幻模式直接变为64/32位保护模式。 引导加载程序确实是64/32位保护模式程序。这就是EFI引导应用程序。在此过程中的任何地方都没有使用实模式或v8086保护模式。
JdeBP 2012年

3
-1。WINE支持在64位Linux上以VM86模式运行16位Windows应用程序。屏幕截图V86-64项目页面。梅赫达德的答案似乎是更有说服力的原因。
休·艾伦

3
@HughAllen:该页面当前显示“当前的64位版本的Linux内核缺少对V86模式的支持,因为这些处理器的本机操作模式(长模式)不支持它。” 和“此补丁非常具有实验性。” 简短的答案是,尽管可以运行16位代码,但是通过完全退出long模式,这样做是不明智的
哈里·约翰斯顿

14

由于64位句柄具有32个有效位

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

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

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

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


3
@乔伊:我不明白你在说什么。如果操作系统是64位Windows,则无法在其上运行16位应用程序。我看不到它们是“ DOS”还是“ Windows”应用程序的事实如何在这里改变了任何方式-无论哪种方式,句柄都需要被应用程序截断。
Mehrdad

1
DOS应用程序没有句柄。实际上,他们(通常)甚至不知道它们在Windows上运行。
乔伊(Joey)

1
...实际上,现在我考虑一下,即使Win16代码也不应该成为太大的问题。您只需要一个查询表。
哈里·约翰斯顿

1
@HarryJohnston:我认为您错过了这个问题。当应用程序调用EnumWindows并且系统中有超过2 ^ 16个窗口时,您建议假想的“查找表”发生什么?
Mehrdad 2013年

1
我在文章中谈论的是内核句柄,而不是窗口句柄。他们是完全不同的东西。16位应用程序甚至可以看到32位窗口吗?这似乎不太可能,因为消息结构不同。如果使用32位wParam向16位应用发送了消息会怎样?另外,请注意,根据msdn.microsoft.com/en-us/library/windows/desktop/…
Harry Johnston

10

对于Windows,这是因为x86版本的OS包含16位仿真,因此它们可以运行那些较早的DOS进程。在x64版本中,它们已经必须模拟x86执行(它们称为WoW64)以允许32位进程运行,而且我猜想使用Wow64进一步模拟16位模拟器会导致太多问题。

少数公认的16位进程将运行,因为仿真是硬编码的,可以处理它们,但其余的将不起作用,因为x64中不包含仿真。

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


14
无需进行任何仿真-x86 / 64可以本机运行这些东西。但是有API重击。微软选择了这个机会来淘汰一种非常古老且几乎未使用的技术。
克里斯·K

@Chris Kaminski-我很惊讶他们会将其作为体系结构决定-x86 vs x64-而不是说“好吧-它是Windows 7,我们不再运行16位进程”。尤其是现在已嵌入7的“ Windows XP Mode”中,即使在x86版本中,似乎也是削减支持的最佳时机。
SqlRyan 2010年

@Chris Kaminski:经过深思熟虑,我认为它必须是在模仿它,而不仅仅是某种API伪造。如果它可以在本地运行其他位构建的代码,那么x64为什么要让Wow64运行32位应用程序-那些也不能在本地运行?
SqlRyan 2010年

@darthcoder:在长(64位)模式下,CPU根本不支持NTVDM要求的虚拟8086模式。因此,要么NTVDM必须成为完整的VM,要么模拟所有内容,否则将被削减。由于已经有足够的虚拟机了(MS也有一个),这并不是一个艰难的决定。我认为这与年龄或使用量无关。
乔伊(Joey)

rwmnau:对于WoW64,没有进行任何仿真(Itanium除外)。x64-64 CPU仍支持32位指令,因此Windows几乎所有要做的就是将CPU切换为32位模式并弄乱一些指针。
乔伊(Joey)2010年

3

如果我错了,请纠正我,但据我了解,这仅仅是因为Windows特定的问题,NTVDM使用虚拟8086模式。x64处理器上的兼容模式(以长模式运行)支持完整的“干净”保护模式,与我在此处找到的地址相比分别为16位和32位:http : //en.wikipedia.org/wiki/Long_mode,但其中一些不兼容386附加功能,例如虚拟8086模式。因此,它最不受支持的原因是,微软对NTVDM进行重新编程并没有回报,这可能需要添加更多的仿真功能,因为某些16位保护模式的应用程序可以使用虚拟8086,即使大多数应用程序都不能使用。我想,只要有足够的工作量,就可以编写比以长模式运行的dosbox更快的内容,因为对16位应用程序提供了硬件支持。


-1。通过本地描述符表支持16位模式寻址(也称为16位段)。。实际上,Linux上的winedvm就是这样做的!甚至还有一个非官方的替代品otvdm
user2284570

好吧,根据我的理解,它(葡萄酒解决方案)包含一个CPU仿真器。因此它没有使用虚拟8086模式。这恰好是可以在NTVDM中实现的解决方案,而无需像DOSBOX(带有Win16)那样模拟整个PC。而且,如果您说在长模式下支持16位保护模式,那么Win16实模式应用程序呢?
MichaelS

它包含一个仿真器,但是如果在Windows上找到了修改本地描述符表的方法,则完全不需要ᴄᴘᴜ仿真。关于实模式,它们也可以用Dosemu(至少是Linux版本)完成的方式进行仿真。Ntvdm最初旨在允许在Mips或PowerPc之类的平台上运行Dos程序,而Windows早期版本支持该程序。它只是一个可选功能,需要在编译时启用。看来源代码泄漏了,只允许某人这样做:columbia.edu/~em36/ntvdmx64.html
user2284570

3

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

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

对于16位Windows应用程序(以16位保护模式运行),原因是MS尚未准备好进行工作以实现合适的兼容性层。有趣的是Wine非常有能力在64位Linux上运行16位Windows应用程序。


1
只是因为64位Windows中没有NTVDM。CPU仍可以在兼容模式下运行16位代码。摘自英特尔手册:“兼容模式(IA-32e模式的子模式)—兼容模式允许大多数旧版16位和32位应用程序在64位操作系统下运行而无需重新编译”
phuclv

据我了解,兼容模式允许使用16位保护模式,但不能使用虚拟8086模式。
plugwash

2

我认为最可能的原因是,只有极少数的PC所有者实际上希望能够在其新的64位硬件上运行旧的16位应用程序。微软可能认为继续支持16位应用程序并不值得。


这是有道理的,但Windows 7 32bit仍支持它,因此显然值得使用它们已经拥有的但不重新实现它(由于没有virtual-8086模式,x86-64将需要它
Earlz 2010年

我当时在想“我们不想维护一个复杂的代码库”。如果他们使用16位,则可能必须支持可追溯到80年代的软件。这可能包括放置丑陋的骇客,以便Lotus 1-2-3仍然可以使用。
乔·普兰特

@Earlz是的,但我认为这是真正的答案,因为要访问16位的Local Descriptor表的真正解决方案是直接执行此操作,而不是通过Vm86模式执行。微软根本没有打扰他们的代码移植。实际上,有一个用于本机64位Windows的Ntᴠᴅᴍ非官方软件替代品
user2284570
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.