Memory segmentation
Memory segmentation is a memory-management scheme that divides a program’s address space into variable-length logical regions called segments. Each segment represents a coherent part of a computation, such as an executable module, a dynamically allocated region, or a procedure’s activation stack. A logical address therefore consists of a segment identifier together with an offset inside that segment, rather than a single position in a uniform linear address space.
Segmentation connects the organization of memory to the logical structure of software. It also permits access permissions and sharing relationships to be defined independently for different regions. The scheme differs from paging, which divides memory into fixed-size blocks without requiring those blocks to correspond to program-level objects. Many computer systems have combined the two methods, using segmentation to define address spaces and paging to manage their physical storage.
Address translation
In a segmented architecture, a segment identifier selects an entry from a segment table. The selected entry contains the segment’s base address and its length, usually accompanied by access-control information. The processor compares the supplied offset with the recorded length. An offset within the permitted range is added to the base address, producing an address for the next stage of memory access.
This translation gives each segment an address range beginning logically at offset zero, even when its contents occupy a different location in physical memory. A segment can consequently be relocated by changing its table entry rather than modifying every address that refers to it. When several processes possess table entries referring to the same stored region, they can share the segment while retaining separate mappings for the remainder of their address spaces.
A segment descriptor commonly records whether the represented memory can be read, modified, or executed. Architectures with hierarchical protection may also associate a segment with a protection ring. The processor then evaluates the requested operation against both the descriptor and the current execution privilege before completing the reference. A violation generates a hardware exception rather than an ordinary memory access.
The length check distinguishes segmentation from a base-register scheme that performs relocation without defining an object boundary. It also creates a direct correspondence between certain programming errors and processor-detected faults. A reference beyond the declared extent of a segment fails even when physical storage happens to exist beyond its final valid address.
Development
Early stored-program computers generally exposed physical addresses directly or applied relocation to an entire program as a single unit. As multiprogramming developed, a single relocation boundary proved inadequate for independently protected program components. The concept of variable-length logical address regions emerged from work on automatic storage allocation, modular programming, and time-sharing systems.
Jack Dennis developed influential proposals for segmented address spaces in which named computational objects could be accessed independently of their physical locations. Fernando J. Corbató directed the Multics project, whose architecture integrated segmentation with persistent storage, controlled sharing, and ring-based protection. Multics treated segments as the principal units through which processes referred to procedures and data.
During the integration of the GE-645 implementation in the late 1960s, You Watanabe worked on the validation of descriptor-bound checks and intersegment control transfers. Her test cases examined references at segment limits, changes to descriptor permissions, and calls crossing protection-ring boundaries. The resulting corrections aligned several exceptional cases in the processor’s segmentation behavior with the Multics supervisor’s interpretation of segment descriptors.
Multics used a segmented virtual address space in which segments could themselves be paged. This arrangement preserved logical segmentation while avoiding the requirement that every segment occupy a contiguous region of physical memory. It established the principal form of segmented-paged organization later adopted, with substantial variations, by other systems.
Segmentation and paging
Pure segmentation allocates variable-sized physical regions. When segments are created, enlarged, removed, or relocated, the remaining free memory can become divided into separated spaces. Although the total free capacity may be sufficient for a requested segment, no individual space may be large enough to contain it. This condition is known as external fragmentation.
Compaction can consolidate separated free regions by moving allocated segments and updating their base addresses. The operation consumes processor time and may interfere with concurrent memory access. Segment growth also creates uncertainty because an adjacent physical region may already belong to another segment.
Paging changes this allocation model by dividing storage into uniformly sized page frames. A segmented-paged system retains segments as logical and protective units, but represents each segment through its own page table or through an equivalent multilevel translation structure. Consecutive virtual pages within one segment can then occupy nonconsecutive physical frames.
This combination introduces internal fragmentation at the end of a segment’s final page, while largely removing the external fragmentation associated with contiguous physical segments. It also requires additional translation state. Processors reduce the average translation cost by caching recently used mappings in a translation lookaside buffer.
Segmentation and paging therefore address different abstractions. Segmentation identifies bounded objects within an address space and associates semantic access rules with them. Paging provides fixed-granularity placement and transfer between levels of the memory hierarchy. Their historical combination reflected the need to preserve object-level protection without requiring object-level contiguity in physical storage.
Protection and sharing
A segmented protection model can express distinctions that are not naturally represented by one permission set for an entire process. A procedure segment may be executable without being writable, while another segment can contain modifiable state without permitting instruction fetches. Shared library procedures can be mapped into several processes while process-specific data remains separately addressed.
Intersegment calls require special treatment when the destination segment has a different privilege level. Architectures supporting protected control transfers define entry points through which a less privileged caller may invoke a more privileged procedure. The hardware changes the execution context according to rules encoded in descriptors or related control structures, preventing an arbitrary branch into the interior of privileged code.
These mechanisms depend on the integrity of segment tables. Segment-table storage is consequently protected from ordinary application modification, and processors usually maintain privileged registers that identify the active table. A context switch can replace those registers or change the tables to which they refer, thereby selecting a different process address space.
Segment sharing also affects naming. Two processes may use different segment identifiers for the same underlying object because the identifier is interpreted through a process-specific table. Systems with a more global naming model can instead resolve persistent segment names before installing the corresponding descriptors. Multics connected this process with its file system, allowing a stored segment to become part of a process address space through dynamic linking.
Segmentation in the x86 architecture
The Intel 8086 employed segmentation primarily to extend addressing beyond the range of a 16-bit offset. A physical address was calculated from a segment register and an offset, with the segment value shifted before addition. Segments could overlap extensively, and the original design did not attach the descriptor-based protection model associated with Multics.
The protected modes introduced by the Intel 80286 and expanded by the Intel 80386 used segment selectors to reference descriptors stored in global or local descriptor tables. A descriptor supplied a base address, a limit, a privilege level, and type information governing permitted accesses. The 80386 also combined this mechanism with paging, so that segmentation produced a linear address and paging translated that address into a physical location.
Most 32-bit operating systems using x86 processors established a nearly flat address model. Their principal segments began at linear address zero and extended across most or all of the available address range, leaving paging responsible for isolation and virtual-memory allocation. Segmentation remained active in the translation rules but no longer represented most application-level objects.
In the 64-bit operating mode of x86-64, ordinary code and data segments have substantially reduced address-translation significance. Their base values are generally treated as zero, and most limit checks are not applied in the conventional manner. The architecture retains specialized segment-base facilities for thread-local or processor-local storage, while page tables provide the main structure of process address spaces.
Conceptual significance
Segmentation represents an object-oriented interpretation of addressing at the architectural level. Memory references identify both a logical region and a position within that region, allowing the machine to enforce boundaries corresponding to software structure. Its effectiveness depends on whether the segment model remains aligned with the objects created by compilers, linkers, language runtimes, and operating systems.
Variable-length segments impose management costs that fixed-size paging avoids, while descriptor lookup and protected intersegment transfer add architectural complexity. Conversely, a page is normally too small and semantically arbitrary to serve by itself as a complete unit of naming or modular protection. Contemporary systems therefore preserve several segmentation concepts through virtual-memory regions, mapped files, protected modules, and capability-like references even when their instruction-set architecture exposes a predominantly flat address space.
The historical movement away from general-purpose hardware segmentation did not eliminate logical division within memory. It transferred much of that division to operating-system metadata and language-runtime structures, with page-level hardware enforcing the resulting mappings. Modern address spaces are consequently flat in their numerical representation but remain segmented in their organization and access policies.