12.1 Segmented and Flat Memory Models

The family of processors that includes 80286, 80386, and 80486 processors implements a segmented memory model in which system memory is divided into 64K segments. In the real mode of these processors, the address of any byte consists of two 16-bit values: a segment address and an offset. (Windows version 3.1 does not support real mode.) In the protected mode of the 80286, 80386, and 80486 processors, the segment address is replaced by a selector value that the processor uses to access the 64K segment. In either mode, a memory object larger than 64K occupies all or part of several segments. An application cannot access such an object as though it consisted of a single contiguous block simply by incrementing a pointer to the memory. Instead, the application can increment only the offset portion of the address, taking care not to exceed the 64K boundary of the segment.

The 80386 processor introduced 32-bit registers that parallel the 16-bit registers of older processors. These registers make it possible for the first time to access memory in segments larger than 64K. In fact, the maximum segment size is potentially so large (232 bytes) that a flat memory model utilizing a single segment is now feasible. In this model, an application's code, data, or both occupy a single segment. The application can manipulate the 32-bit offset portion of the memory as though it were a simple pointer. The application can increment and decrement the offset portion of the memory throughout the address space without having to deal with multiple segment boundaries.

To a certain extent, the flat memory model most closely resembles the tiny memory model, in which both code and data occupy a single segment; of course, the segment is much larger than the 64K limit imposed by the segmented memory model. As in the tiny memory model, the beginning of the segment of the flat memory model can appear anywhere in memory. In other words, the segment-descriptor portion of the address can refer to virtually any location in memory. As the application moves through memory, the segment descriptor never changes. Only the offset is incremented and decremented to point to different locations in memory.

The flat memory model makes it possible for you to ignore segments and segment registers. The segment registers are loaded at the start of the 32-bit code and are then left alone. The rest of the application runs in this purely 32-bit offset mode—all pointers are near pointers.

It is not possible to implement a Windows application by using an exclusively flat memory model. Because Windows itself relies on the 16-bit segmented memory model, any application that interacts with Windows must implement at least one 16-bit code segment. Despite this limitation, it is possible for a Windows application to reside largely in one or more 32-bit code segments and to use 32-bit data segments. The WINMEM32.DLL library makes this possible in a way that ensures the application cooperates fully with Windows and similar platforms. For more information, see Section 12.3.1, “Flat Memory Model Limitations.”