Why is it that:

  • a 32-bit OS, when installed on a 64-bit CPU, can run old 16-bit applications,
  • but if you install a 64-bit OS it can't run those applications directly and need some sort of emulation (that doesn't always work perfectly)?

To be more specific, I have an 64-bit processor (Intel Core 2 Duo). When I had Windows XP and Windows 7 (both 32-bit) installed, they could run old DOS and 16-bit Windows applications.

Now I have installed the 64-bit edition of Windows 7. Why can't it run those same applications anymore?

  • 3
    I think that has less to do with the bits and more with the guest operating system. What OS's are you referring to specifically?
    – Pekka
    Commented May 13, 2010 at 14:40
  • Will it run under DOSBox?
    – Penguat
    Commented May 13, 2010 at 15:30
  • 1
    There is a utility called DOSBOX its a 16 bit emulator that gives your 16 bit program a virtual 16 bit computer to work on, and its free.
    – user114474
    Commented Jan 20, 2012 at 4:22
  • 2
    You're confusing Windows with all OS.
    – Ken Sharp
    Commented Jan 1, 2018 at 1:50
  • 1
    @Synetech the ᴄᴘᴜ can run directly enable 16‑bits pointers segments through the local descriptor table of the process. Commented Jul 21, 2019 at 8:59

6 Answers 6


From my understanding, it's because when running in Long Mode (x64 native), the CPU itself doesn't support going into 16 bit mode. See Wikipedia. So, in order to support 16 bit mode, the NTVDM (the 16 bit layer in Windows) would have to fully emulate a 16 bit processor.

I suppose they weighed re-implementing an emulation layer vs using already extant virtualization software (VirtualPC, VirtualBox) to handle this, and it was decided to cut the VDM.

  • 9
    Quoting from Wikipedia: Versions of Windows NT for 64-bit architectures (x64 and IA-64) do not include the NTVDM and are unable to run DOS or 16-bit Windows applications. This is because, in an x86-64 CPU, virtual 8086 mode is available as a sub-mode only in its legacy mode (for running 16- and 32-bit operating systems), not in the native, 64-bit long mode; a hard reset of the CPU is required to switch to legacy mode. So the only way how NTVDM has worked so far isn't available anymore and full VMs are out there aplenty, so NTVDM was cut.
    – Joey
    Commented May 14, 2010 at 6:57
  • 5
    Yuck, I can't believe they dumped the V86 mode. Might as well toss real mode completely and demand 32/64 bit boot loaders if you're going to do that. Commented Jul 23, 2010 at 18:50
  • 7
    That is exactly what has already happened, M. Knoblauch. A modern x86 machine with EFI firmware goes straight from unreal mode in its first few instructions to 64/32-bit protected mode. The boot loaders are indeed 64/32-bit protected mode programs. That's what EFI boot applications are. There's no use of real mode or v8086 protected mode anywhere in the process.
    – JdeBP
    Commented Jan 20, 2012 at 8:41
  • 4
    -1. WINE supports running 16-bit Windows apps in VM86 mode on 64-bit Linux. screenshot. V86-64 Project page. Mehrdad's answer seems like the more compelling reason.
    – Hugh Allen
    Commented Dec 15, 2012 at 0:36
  • 4
    @HughAllen: that page currently says "Currently 64-bit version of linux kernel lacks support of V86 mode because it is not supported in native operating mode (long mode) of these processors." and "This patch is very experimental." The short answer is that although it is possible to run 16-bit code, by exiting long mode completely, it isn't sensible to do so. Commented Oct 15, 2013 at 3:41

Because 64-bit handles have 32 significant bits:

Note that 64-bit Windows does not support running 16-bit Windows-based applications.
The primary reason is that handles have 32 significant bits on 64-bit Windows.
Therefore, handles cannot be truncated and passed to 16-bit applications without loss of data.

In Windows, programs pass around "handles" to the OS and vice-versa (which are numbers that the OS uses to uniquely identify a particular resource, such as a window).

To support 16-bit programs, 32-bit Windows only generates a handles that have 16 significant bits -- the 16 upper bits are ignored by the OS (even though programs are not to be taking advantage of this fact). So no program can interact with more than 216 objects, which is actually rather low.

However, in order to improve this, 64-bit Windows increased the number of significant bits in a handle to 32. But now that means that handles cannot be passed to 16-bit programs without loss of information. So 16-bit programs cannot run on 64-bit Windows.

  • 3
    @Joey: I don't understand what you're saying. If the OS is 64-bit Windows, then 16-bit applications can't run on it, period. I don't see how the fact that they're "DOS" or "Windows" application changes anything here -- either way, handles would need to be truncated by the application.
    – user541686
    Commented Dec 14, 2012 at 6:19
  • 2
    DOS applications have no handles. In fact, they (usually) don't even know they're running on Windows.
    – Joey
    Commented Dec 14, 2012 at 6:20
  • 2
    ... actually, even Win16 code shouldn't be too much of a problem, now that I think about it. All you'd need is a lookup table. Commented Oct 15, 2013 at 3:52
  • 1
    @HarryJohnston: I think you're missing the problem. What do you propose should happens with your imaginary "lookup table" when an application calls EnumWindows and there are more than 2^16 windows in the system?
    – user541686
    Commented Oct 15, 2013 at 4:43
  • 1
    I was talking about kernel handles as per the article, not window handles. They're completely different things. Do 16-bit applications even see 32-bit windows? It seems unlikely, because the message structures are different; what would happen if a 16-bit app was sent a message with a 32-bit wParam? Also, note that the maximum number of window handles is still 2^16 according to msdn.microsoft.com/en-us/library/windows/desktop/… Commented Oct 15, 2013 at 21:32

For Windows, it's because the x86 versions of the OS includes 16-bit emulation that allows them to run those older DOS processes. In the x64 versions, they already have to emulate x86 execution (they call it WoW64) to allow 32-bit processes to run, and I guess using Wow64 to further emulate the 16-bit emulator caused too many problems.

A handful of recognized 16-bit processes will run because the emulation is hard-coded to handle them, but the rest don't work because emulation isn't included in x64.

See the following Microsoft article about lack of 16-bit support: https://learn.microsoft.com/en-us/troubleshoot/windows-client/application-management/x64-windows-not-support-16-bit-programs

Update: Micrsoft seems to have added some 16-bit emulation back into modern versions of Windows, albeit in the form of an emulator/VM. Maybe modern Virtualization has made this easier, but interesting choice: https://www.groovypost.com/howto/enable-16-bit-application-support-windows-10/

  • 14
    There's no emulation going on - x86/64 can run these things natively. There is API thunking going on however. Microsoft has chosen this opportunity to retire a significantly old and mostly unused technology.
    – Chris K
    Commented May 13, 2010 at 14:53
  • @Chris Kaminski - I'm surprised that they'd do that as an architecture decision - x86 vs x64 - as opposed to saying "Alright - it's Windows 7, and we're not running 16-bit processes anymore". Especially with "Windows XP Mode" now embedded in 7, it seems like the perfect time to cut support even in the x86 version.
    – SqlRyan
    Commented May 13, 2010 at 17:31
  • @Chris Kaminski: After giving it some more thought, I think it has to be emulating it, not just some kind of API-mucking. If it could run code of a different bit-build natively, then why would x64 have Wow64 to run 32-bit apps - wouldn't those run natively as well?
    – SqlRyan
    Commented May 13, 2010 at 21:34
  • 1
    rwmnau: For WoW64 there is no emulation going on (except for Itanium). x64-64 CPUs still support the 32-bit instructions so almost all Windows has to do is switch the CPU in 32-bit mode and mess with a few pointers.
    – Joey
    Commented May 14, 2010 at 7:04
  • 1
    @SqlRyan They do run natively. You need Wow64 to provide an API based on 32-bit pointers. The 64-bit native API, naturally enough, uses 64-bit pointers. Commented Jul 18, 2014 at 22:19

The situation is different for Dos applications and 16 bit windows applications.

For Dos applications the problem is that virtual 8086 mode is not available under long mode. This is a CPU architecture limitation.

For 16 bit Windows appliations (which run in 16 bit protected mode) the reason is that MS wasn't prepared to do the work to implement a suitable compatibility layer. Amusingly Wine is perfectly capable of running 16 bit windows apps on 64-bit linux.

  • 1
    it's just because there's no NTVDM in 64-bit Windows. The CPU can still run 16-bit code in compatibility mode. From Intel manual: "Compatibility mode (sub-mode of IA-32e mode) — Compatibility mode permits most legacy 16-bit and 32-bit applications to run without re-compilation under a 64-bit operating system"
    – phuclv
    Commented Feb 24, 2018 at 12:50
  • 2
    As I understand it compatibility mode allows 16 bit protected mode, but not virtual 8086 mode.
    – plugwash
    Commented Nov 7, 2019 at 0:16

Correct me if I'm wrong, but to my understanding it is just because of Windows-specific problem that NTVDM is using virtual 8086 mode. Compatibility mode on x64 processors (running in long mode) supports full 'clean' protected mode, 16 and 32 bit from what I've found here: http://en.wikipedia.org/wiki/Long_mode, but not some of the 386 additions such as virtual 8086 mode. So it is not supported most likely because it doesn't pay off for Microsoft to reprogram NTVDM, which would probably require adding some more emulation because some 16-bit protected mode applications can use virtual 8086, even if most do not. I suppose with enough labor it is possible to write something faster than dosbox running in long mode, since there is hardware support for 16bit apps.

  • 2
    −1. 16 bits mode addressing aka 16 bits segment is supported through the local descriptor table.. In fact winedvm on on Linux does just that ! There’s even an unofficial replacement called otvdm. Commented Jul 20, 2019 at 18:13
  • Well, according to my understanding it (wine solution) contains a CPU emulator. So it is not using virtual 8086 mode. That's precisely the solution which, potentially, could be implemented in NTVDM, without emulating the whole PC, like DOSBOX (with Win16) does. And if you say that 16 bit protected mode is supported under long mode, then what about Win16 real-mode apps?
    – MichaelS
    Commented Jul 21, 2019 at 7:53
  • It contains an emulator but if a way to modify the local descriptor table is found on Windows, then no ᴄᴘᴜ emulation at all would be required. About real mode they can also be emulated in such way as done by Dosemu (the Linux version at least). Ntvdm was initially designed for allowing running Dos program on platforms like Mips or PowerPc which was supportted in Previous version of Windows. It’s just an optional Feature which needs to be enabled at compile time. And it appears source code was leaked allowing someone to do just that : columbia.edu/~em36/ntvdmx64.html Commented Jul 21, 2019 at 8:11

I think that the most likely reason is that only a tiny percentage of PC owners actually want to be able to run old 16 bit applications on their new 64 bit hardware. Microsoft probably figured that it wasn't worth their while continuing to support 16 bit applications.

  • This makes sense except for Windows 7 32bit still supports it, so apparently it's worth it to use what they already have but not reimplement it(as would be needed for x86-64 due to no virtual-8086 mode
    – Earlz
    Commented May 14, 2010 at 1:09
  • I was thinking that "we don't want to maintain a complicated code base". If they kept in 16-bit, they might have had to support software that dates back to the 80s. This may include putting in ugly hacks so that Lotus 1-2-3 still works.
    – Joe Plante
    Commented Aug 9, 2015 at 20:25
  • @Earlz yes but I think this is the real answer as the real solution in order to access the Local Descriptor table for 16 bits is to do it directly and not through Vm86 mode. Microsoft simply didn’t bother porting their code. There’s in fact an Ntᴠᴅᴍ unofficial software replacement designed for native 64‑bits Windows. Commented Jul 20, 2019 at 18:11

You must log in to answer this question.