Each program is divided into blocks of unequal size but with semantics meaning.
Example: Code, global variables, local variables, stack, …
Contiguous memory is allocated for each segment for the exact amount needed (first-fit, best-fit).
A logical address is two dimensional with segment number and offset in segment.
Each process has a segment table that specify where the segments are allocated.