Fixed and Moveable Segments

Every segment in Windows' total memory space is marked with certain attributes that tell Windows how to manage the segment. First and foremost, segments are marked as either ”fixed“ or ”moveable.“ Windows can move moveable segments in memory if necessary to make room for other memory allocations. When Windows moves a segment in memory, all existing near pointers to that segment continue to be valid, because near pointers reference an offset from the beginning of a segment. However, far pointers become invalid when the segment they reference is moved. A fixed segment cannot be moved in memory. Segments must be marked as fixed if Windows is incapable of modifying an existing far pointer to the segment.

In protected mode, all program segments are moveable because Windows can move the segment without changing the segment address. Windows need only change the physical base address in the descriptor table.

Most segments—including the segments allocated for your program's code and data—are moveable, but some exceptions exist. Whenever Windows gives your program a far pointer, the pointer references a fixed data segment. For instance, when your Windows program begins executing, Windows passes a parameter to WinMain that we call lpszCmdLine. This is a far pointer to an area of memory that contains a command-line argument for the program. I mentioned above that this command-line string is stored in a program overhead segment that Windows creates for each instance of a program. This program overhead segment must be fixed. If Windows moves it, the command-line pointer passed to your program becomes invalid.

Here's one way Windows deals with moveable segments: You've seen how Windows and your programs use numbers called ”handles.“ In many cases, the handles are really near pointers. Windows maintains a segment called BURGERMASTER (named after a favorite restaurant of the early Windows developers) that contains a master handle-to-memory table. The handle points to a small area of memory within BURGERMASTER that contains the segment address of the item that the handle references. When Windows moves the segment that contains the item, it can adjust the address in BURGERMASTER without invalidating the handle. BURGERMASTER is itself a moveable segment.

All non-Windows MS-DOS programs are assigned fixed segments when they run under Windows. Windows cannot determine how these programs reference memory, so Windows has no choice but to make them fixed. However, you should try very hard to ensure that the code and data segments of your Windows programs (as well as any additional segments your programs allocate) are moveable segments. Fixed segments stand like brick walls in memory space and clog up Windows' memory management. Users quickly learn which programs seem to use little memory (because they use moveable segments) and which seem to use a lot of memory (because they use fixed segments). Users have a name for programs that use a lot of memory. They say, ”This program is a real pig.“ Your goal should be to write programs that are not pigs.