←back to thread

331 points giuliomagnifico | 1 comments | | HN request time: 0.001s | source
Show context
deaddodo ◴[] No.45378189[source]
Nitpick: The author states that removal of 16-bit in Windows 64 was a design decision and not a technical one. That’s not quite true.

When AMD64 is in one of the 64-bit modes, long mode (true 64-bit) or compatibility mode (64-bit with 32-bit compatibility), you can not execute 16-bit code. There are tricks to make it happen, but they all require switching the CPU mode, which is insecure and can cause problems in complex execution environments (such as an OS).

If Microsoft (or Linux, Apple, etc) wanted to support 16-bit code in their 64-bit OSes, they would have had to create an emulator+VM (such as OTVDM/WineVDM) or make costly hacks to the OS.

replies(3): >>45378270 #>>45378503 #>>45378862 #
jcranmer ◴[] No.45378503[source]
I've written code to call 16-bit code from 64-bit code that works on Linux (because that's the only OS where I know the syscall to modify the LDT).

It's actually no harder to call 16-bit code from 64-bit code than it is to call 32-bit code from 64-bit code... you just need to do a far return (the reverse direction is harder because of stack alignment issues). The main difference between 32-bit and 16-bit is that OS's support 32-bit code by having a GDT entry for 32-bit code, whereas you have to go and support an LDT to do 16-bit code, and from what I can tell, Windows decided to drop support for LDTs with the move to 64-bit.

The other difficulty (if I've got my details correct) is that returning from an interrupt into 16-bit code is extremely difficult to do correctly and atomically, in a way that isn't a problem for 32-bit or 64-bit code.

replies(1): >>45379259 #
deaddodo ◴[] No.45379259[source]
Executing 16-bit code in Compatibility Mode (not Long Mode) is possible, that's not the problem. The problem is lack of V86 allowing legacy code to run. So Real Mode code is out wholesale (a sizable chunk of legacy software) and segmented memory is out in Protected Mode (nearly the totality of remaining 16-bit code).

So yes, you can write/run 16-bit code in 64-bit Compatibility Mode. You can't execute existing 16-bit software in 64-bit Compatibility Mode. The former is a neat trick, the latter is what people actually expect "16-bit compatibility" to mean.

replies(2): >>45379548 #>>45432033 #
gldrk ◴[] No.45432033{3}[source]
Properly written Win16 applications are agnostic with respect to memory protection. Windows 3.0 could run in real mode (8086+), standard mode (80286+), or enhanced mode (80386+). Enhanced mode used V86 mode, which didn’t exist on the 80286, to support DOS console windows. In standard mode, Windows suspended itself to allow running DOS applications.

Real mode support was in fact dropped in Windows 3.1, so any program that runs under that is guaranteed to run under Linux/Wine (though not guaranteed not to crash because of some unimplemented API).

In protected mode, all Win16 code runs in ring 1 or 3, including all drivers and application programs, as well as the so-called ‘kernel’, which is just a shared library that provides support for coroutines, among other things. The actual kernel that runs in ring 0 is the DPMI host.

Memory segmentation is 100% supported on AMD64 in compatibility mode. This is entirely independent of the default operand size: it is purely a historical coincidence that 32-bit code segments tend to go hand-in-hand with flat memory models.

replies(1): >>45454767 #
deaddodo ◴[] No.45454767{4}[source]
Or you can just join the conversation in the middle instead of seeing all of that addressed in the replies:

> even with LDTs, segments will not function with the legacy 16-bit wraparound; nor can you run 16-bit code segments. [...] <and no far pointers>

And, most importantly:

> That being said, this isn't worth arguing over. If you can provably run late 1980s-early 1990s 16-bit code in AMD64 compatibility mode, with full execution protections and support of even most, not all, commercial software; that goes against the general understanding of those architectures. Document it and add it to the academic sphere to expand the knowledge.

Despite that entire conversation happening almost a week ago.

replies(1): >>45589787 #
1. gldrk ◴[] No.45589787{5}[source]
>even with LDTs, segments will not function with the legacy 16-bit wraparound

Yes, this is why KERNEL exports __AHSHIFT and __AHINCR.

>Despite that entire conversation happening almost a week ago.

It’s difficult enough to find correct information about this stuff. There is no harm in providing corrections.