On modern computers, programs run inside a virtual address space: the memory addresses a program uses in its instructions are not real physical addresses, but only virtual addresses. The hardware (MMU, which stands for Memory Management Unit) does a translation between virtual address and physical address before issuing queries on the memory bus.
The goals of virtual address spaces are many:
In the segmentation scheme, a virtual memory address is a SEG:OFFS pair. Each segment has a base, a size, and a protection mode (read-only or not, ...). The physical address is computed by adding the offset to the base of the segment, and checking if it does not overflow the segment size. This is a very simple operation for the hardware.
Usually, segments can be omitted, using a default one (or a default one for the code, a different default one for the stack, and a third one for data), but programs wanting to use some features like memory sharing have to be aware of segments.
Additionnaly, the granularity of segmentation is usually low, and moving a full segment to back storage can be very slow. Another drawback is that a segment must be contiguous in physical memory, creating fragmentation problems.
Paging is amore flexible VM design than segmentation. The virtual addess space is linear and contiguous (going from 0 to on ia-32), and divided in small pages (of 4096 bytes on ia-32). Each virtual page is mapped to a physical page, or marked as invalid in a page table. This scheme allows better granularity, and is completely transparent for programs. Each process has is own mapping between virtual memory and physical memory, and memory sharing can be done by mapping pages to the same physical frames. This scheme requires more processing from the MMU, and such conversion between virtual addresses and physical addresses are cached in a special cache called TLB (Translation Look-aside Buffer).
When a page marked as invalid is accessed, a ``page fault'' exception occurs, and the control is given to the kernel. The operating system can then reload the page if it was transferred to back-end storage, and allow the faulting program to go on.