Thunk (compatibility mapping)
Thunk (or thunking) refers to the creation of a 16-bit virtual DOS machine (VDM) within a 32-bit operating platform so that there is backward compatibility for applications using older code or system calls.
OS/2 & Windows 16-bit address hack
A flat thunk consists of a DLL (or, if bidirectional compatibility is needed, a pair of DLLs—one 32-bit and one 16-bit) that is used to translate calls from 32-bit code to 16-bit code. 16- and 32-bit memory addresses work very differently: 16-bit addresses consist of two parts, a pointer to a memory segment, and the offset from the start of that memory segment; whereas a 32-bit process memory pointer consists of the "flat" virtual address of the memory being accessed ("flat" meaning there is no separation of segment and offset part). To allow the two DLLs to communicate, some intermediate code must be used to translate memory addresses (pointers) between platforms.
The most common usage is in the Win16/Win32 APIs, where thunking is used to convert a 16-bit address into a 32-bit equivalent or vice versa. An early example was the 32-bit TCP/IP protocol stack for Windows for Workgroups version 3.11. Code-named "Wolverine", this was an early implementation of the TCP/IP stack that would later ship with Windows 95. While not initially shipped with Windows for Workgroups, it was available on the NT 3.51 Server CD as an install disk creation utility (at the time, it was more common on 16-bit Windows for IP to be used via Novell's Internetwork Packet Exchange). To allow this stack to operate with 16-bit applications, a version of the 16-bit winsock.dll library was included that simply thunked WinSock calls into the 32-bit stack.
Microsoft later created a mostly-complete thunking layer, called Win32s, which allowed 32-bit Windows applications (written to a specific subset of the Win32 API, hence the "s" in Win32s) to run on top of 16-bit Windows 3.1x. In many ways, Windows 95 was essentially a full-scale expansion of Win32s, because many of the underpinnings of Win95 were still 16-bit.
Thunking was used in Windows NT/2000 compatibility subsystems: the OS/2 subsystem allowed 16-bit console-mode OS/2 applications to run on Windows NT (x86 only), and the Windows on Windows (a.k.a. "WoW") subsystem permitted 16-bit Windows applications the same ability. The OS/2 subsystem was dropped after Windows 2000, and the WoW subsystem is not provided in 64-bit versions of Windows. 64-bit versions of Windows provide a similar thunking layer, WoW64, to allow use of 32-bit Windows applications.
Certain implementations of relocatable code use local thunks to call library functions. Dynamic library calls in the code jump to thunks in a jump table; the jump table is replaced (by a dynamic linker) with short functions that either load the applicable library (as needed) or jump to the appropriate point in an already-loaded library. This form of thunk performs essentially the same task as the thunk-as-delayed-computation in lazy evaluation (call-by-need): it computes a result, or returns the previously computed and cached value.
Software-based virtual memory systems may use a thunk to perform the mapping from virtual addresses to physical addresses; however, most modern systems do this computation in a specialized memory management unit in hardware. Microsoft Windows 3.0 and earlier, when running in real mode, used a thunk to replace any entry points to a function in a dynamic-link library or executable when the code segment containing that function was discarded (similar to swapped out in a conventional virtual memory system). This is an example of a software-based virtual memory system.
The original Microsoft thunk documentation describes thunk in terms of the
MakeProcInstance function, which created two-instruction thunks (
mov ax,<data segment selector>
- Michael Geary. "FixDS – a bit of Windows history".