Why can't a 64 bit OS run a 16 bit application?

40

19

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 616-bit Windows applications.

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

Bob

Posted 2010-05-13T14:38:35.550

Reputation:

3I 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 – 2010-05-13T14:40:54.580

Will it run under DOSBox? – Penguat – 2010-05-13T15:30:52.820

1You're confusing Windows with all OS. – Ken Sharp – 2018-01-01T01:50:12.963

@Synetech the ᴄᴘᴜ can run directly enable 16‑bits pointers segments through the local descriptor table of the process. – user2284570 – 2019-07-21T08:59:38.420

@user2284570, gotta love backwards-compatibility. (Though to be fair, backwards-compatibility is also what results in piles of messy, tangled code and limitations that could be avoided by skipping it. ) – Synetech – 2019-07-22T12:21:44.997

I agree with Pekka, the fact is that a 64-bit (hardware) system can run 16-bit code (heck, even 1-bit code if the OS were so designed). The real catch is that the CPU cannot directly run the 16-bit code due to things like different pointer sizes, but these issues can be abstracted away by the OS. The limitation is an artificial one that Microsoft imposed to simplify things (though they still emulated 32-bit because there is still so much 32-bit code). There are other OSes (*nix?) that can run 16-bit code without issue. – Synetech – 2012-09-01T20:59:40.533

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.

– None – 2012-01-20T04:22:42.937

Answers

25

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.

Matt Sieker

Posted 2010-05-13T14:38:35.550

Reputation: 526

1As i understand it, 16-bit protected-mode code will run in long mode, but real-mode and virtual-8086 mode code won't. And 16-bit code in Windows is run in virtual 8086 mode. – None – 2010-05-13T18:21:47.407

@cHa 16 bit windows executables are ran in 16-bit protected mode I believe, but he is concerned with a DOS executable which expects real/virtual-8086 mode. – Earlz – 2010-05-14T01:07:26.080

7

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 – 2010-05-14T06:57:45.220

1This answer and the comments to it confuse virtual 8086 mode (aka DOS) with 16 bit protected mode (aka win16). The former is not accessible under long mode, the latter is (and is used by wine) – plugwash – 2016-04-07T14:19:43.667

5Yuck, 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. – Brian Knoblauch – 2010-07-23T18:50:02.540

@MattSieker −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.

– user2284570 – 2019-07-20T18:13:09.973

@HughAllen no it doesn’t use Vm86 but the local descriptor table of the process with the modify_ldt() system call to enable 16 bits segment addressing. – user2284570 – 2019-07-20T18:15:31.227

@Joey not everything stated on Wikipedia is true. I edited the article with references in order to reflect this. – user2284570 – 2019-07-21T09:01:04.113

5

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 – 2012-01-20T08:41:25.493

@Joey the wikipedia page you quoted no longer claims a reset is required to switch to legacy mode, and I don't think it is either - see the heading "Exiting from Long Mode" at The Real, Protected, Long mode assembly tutorial for PCs

– Hugh Allen – 2012-12-13T05:34:51.450

Hugh: That's a little besides the point, though, as it's still not possible: Once the CPU enters Long mode, VM86 is not supported anymore. That is the reason why 64-bit OSs cannot run 16-bit applications. However, emulators like DosBox will run fine your 16-bit old game. — from the very same page you linked. – Joey – 2012-12-13T09:00:27.273

@Joey but surely any limitations of long mode don't matter if you can leave long mode and return to it whenever you want? – Hugh Allen – 2012-12-13T15:08:37.097

You cannot leave Long Mode for the V86 mode. It doesn't matter if you can leave to compatibility mode or not, that's not what you want. – Joey – 2012-12-13T17:51:41.723

@Joey not true - read the article I linked. Leaving 64-bit and returning to compatibility mode is a separate step from (and the one just before) leaving long mode (and returning to legacy mode). See also wikipedia's AMD64 state diagram - it has bidirectional arrows for all transitions.

– Hugh Allen – 2012-12-13T22:54:58.003

3

-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 – 2012-12-15T00:36:39.873

Yes, this answer is wrong. Microsoft explicitly states the reason on the page my answer linked to. – user541686 – 2013-08-30T08:41:58.347

3@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. – Harry Johnston – 2013-10-15T03:41:34.817

14

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.

user541686

Posted 2010-05-13T14:38:35.550

Reputation: 21 330

Looking at this topic again, I suspect that whoever wrote the linked document at Microsoft was confused, because as @HarryJohnston points, out, USER and GDI handles are still 16 significant bits on Win64, and moreover, it seems that kernel handles were already at least 24 significant bits on Win32

– Hugh Allen – 2019-07-22T04:46:32.473

Why was this downvoted? – user541686 – 2012-07-22T06:45:17.563

Probably because the reason refers to 16-bit Windows applications while the question was about 16-bit DOS applications. – Joey – 2012-12-14T06:16:28.773

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 – 2012-12-14T06:19:30.857

1DOS applications have no handles. In fact, they (usually) don't even know they're running on Windows. – Joey – 2012-12-14T06:20:04.937

@Joey: The EXE or COM file itself is irrelevant; the "application" is more than just the executable. DLLs/modules are there too. The (user-mode) WOW emulator (NTVDM) is also part of the application, and it does need handles, no? – user541686 – 2012-12-14T06:20:59.093

As the article says, this issue makes running Win16 code implausible, but it doesn't mention 16-bit DOS code. The NTVDM might or might not depend on handles being 16-bits, even when only running DOS, but if so, it shouldn't be particularly hard to fix. In contrast, the complications involved in exiting long mode would affect the entire kernel - for example, what happens if a hardware interrupt arrives while running 16-bit code? So, on the whole, while it's entirely plausible that MS would have abandoned NTVDM for this reason alone, that's speculation; the CPU issues are more fundamental. – Harry Johnston – 2013-10-15T03:49:17.013

1... 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. – Harry Johnston – 2013-10-15T03:52:59.493

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 – 2013-10-15T04:43:09.257

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 http://msdn.microsoft.com/en-us/library/windows/desktop/ms725486%28v=vs.85%29.aspx

– Harry Johnston – 2013-10-15T21:32:41.697

@HarryJohnston: Good point, I didn't know the window handle sizes didn't change. Maybe a lookup table could be used then? I'm not sure. – user541686 – 2013-10-15T21:42:05.563

At a guess, they'd have decided not to bother anyway. We are talking about very old code here. :-) – Harry Johnston – 2013-10-15T21:47:55.150

10

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 "No 16-bit code" at the MSKB article: http://support.microsoft.com/kb/282423

SqlRyan

Posted 2010-05-13T14:38:35.550

Reputation: 1 021

@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. – David Schwartz – 2014-07-18T22:19:02.927

14There'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 – 2010-05-13T14:53:44.257

@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 – 2010-05-13T17:31:41.777

@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 – 2010-05-13T21:34:00.507

@darthcoder: The CPU simply doesn't support the virtual 8086 mode required by NTVDM in long (64 bit) mode. Therefore either NTVDM would have to become a full VM, emulating everything or get cut. Since there are enough VMs out there already (and MS has one too) that wasn't a hard decision. I don't think it has anything to do with how old that was or how much used. – Joey – 2010-05-14T07:01:07.733

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 – 2010-05-14T07:04:12.680

@SqlRyan It’s partially true : they used Vm86 in order to provide 16-bits segment addressing instead of using the local descriptor table. – user2284570 – 2019-07-20T19:27:26.453

4

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.

plugwash

Posted 2010-05-13T14:38:35.550

Reputation: 4 587

1it'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 – 2018-02-24T12:50:03.763

1As I understand it compatibility mode allows 16 bit protected mode, but not virtual 8086 mode. – plugwash – 2019-11-07T00:16:32.160

3

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.

MichaelS

Posted 2010-05-13T14:38:35.550

Reputation: 199

−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.

– user2284570 – 2019-07-20T18:13:16.687

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 – 2019-07-21T07:53:55.450

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 : http://www.columbia.edu/~em36/ntvdmx64.html

– user2284570 – 2019-07-21T08:11:23.043

2

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.

Stephen C

Posted 2010-05-13T14:38:35.550

Reputation: 355

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 – 2015-08-09T20:25:39.897

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 – 2010-05-14T01:09:08.123

@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.

– user2284570 – 2019-07-20T18:11:04.003