CampusFlow
ArchitectureSegmentation

🔀 Segmentation

Segmentation divides memory into variable-sized logical units (segments) that correspond to program structure: code, data, stack, and heap.

Memory Segments

â„šī¸

Logical Division

Unlike paging (fixed-size, unaware of program structure), segmentation matches the programmer's view. Each segment has a base address and limit for protection.

Code (Text)

Executable instructions. Read-only, fixed size. Shared between processes for memory efficiency.

Data

Global and static variables. Read-write. Includes BSS (uninitialized data, zero-filled).

Stack

Function call frames, local variables, return addresses. Grows downward. LIFO structure per thread.

Heap

Dynamically allocated memory (malloc/new). Grows upward. Shared across threads of a process.

Segment Table & Address Translation

💡

Address Format

Logical address = (segment_number, offset). The segment table maps segment number to base physical address and limit. If offset exceeds limit → segmentation fault.

Segment Table

Seg #NameBaseLimitProt
0Code0x100000x3000R
1Data0x200000x4000R/W
2Stack0x300000x1000R/W
3Heap0x400000x2000R/W

📱 Interactive Translation

Segmentation with Paging (Seg-Paged)

â„šī¸

Hybrid Approach

Combines segmentation's logical organization with paging's elimination of external fragmentation. Used in x86-64 architecture. Virtual address = Segment + Page Number + Offset.
V
Virtual Address

Segment # + Offset within segment

S
Segment Table

Look up segment base + limit. Check offset ≤ limit.

L
Linear Address

Base + Offset = linear address (intermediate)

P
Page Tables

Linear address → Page # + Offset → Page walk

P
Physical Address

Frame # + Offset → actual RAM access

Benefits

  • ✓ Each segment is paged — no external fragmentation
  • ✓ Segments provide logical structure and protection
  • ✓ Page sharing within segments is possible
  • ✓ Combined: best of both worlds

Drawbacks

  • ✗ Two levels of indirection = more TLB/page table lookups
  • ✗ More complex hardware (MMU must handle both)
  • ✗ Segment limits can waste page table entries
  • ✗ Variable segment sizes complicate OS management

Protection & Sharing

Protection

Each segment has protection bits in the segment descriptor:

Code Segment:Read-only, Execute(No writes allowed)
Data Segment:Read/Write(Full access)
Stack Segment:Read/Write(No execution)

Sharing

Multiple processes can share the same segment via their segment tables:

  • ✓ Shared libraries (.so/.dll) loaded as shared code segments
  • ✓ Each process' segment table entry points to same physical segment
  • ✓ Protection bits can make shared segment read-only
  • ✓ Saves significant memory (e.g., libc shared across 100 processes)

Segmentation vs Paging

PropertyPagingSegmentation
SizeFixed-size pagesVariable-sized segments
ViewHardware-orientedProgrammer-oriented
FragmentationInternal (wasted space within page)External (gaps between segments)
ProtectionPer-page bitsPer-segment descriptor
SharingShared as pages (coarse)Shared as segments (logical units)
Table SizeLarge (one entry per page)Small (one entry per segment)
Addressing(page#, offset)(segment#, offset)
Fault HandlingPage faultSegmentation fault (segviolation)

Code Example: Segment-Based Protection

python

class SegmentTableEntry:
    def __init__(self, base, limit, prot):
        self.base = base
        self.limit = limit
        self.prot = prot  # "R", "RW", "RX", "RWX"

def translate(segment_table, seg_num, offset):
    if seg_num < 0 or seg_num >= len(segment_table):
        raise SegmentationFault("Invalid segment")

    entry = segment_table[seg_num]
    if offset > entry.limit:
        raise SegmentationFault(
            f"Offset {offset} exceeds limit {entry.limit}"
        )

    physical = entry.base + offset
    return physical

# Example usage
seg_table = [
    SegmentTableEntry(0x10000, 0x3000, "RX"),  # Code
    SegmentTableEntry(0x20000, 0x4000, "RW"),  # Data
    SegmentTableEntry(0x30000, 0x1000, "RW"),  # Stack
]

# Access code segment, offset 0x100
addr = translate(seg_table, 0, 0x100)  # → 0x10100

# Access beyond limit -> Segmentation fault!
try:
    addr = translate(seg_table, 0, 0x4000)
except SegmentationFault as e:
    print(f"Fault: {e}")

Interview Questions

What is segmentation and how does it differ from paging?

Segmentation divides memory into variable-sized logical units (code, data, stack, heap) that match program structure. Paging divides memory into fixed-size pages. Segmentation has no internal fragmentation (segments are exactly sized) but suffers external fragmentation. Paging has internal fragmentation but eliminates external fragmentation. Most modern systems use both (seg-paged).

How does segmentation provide memory protection?

Each segment descriptor in the segment table contains a base address, limit (size), and protection bits (R/W/X). The MMU checks every access: if offset > limit, a segmentation fault is raised. This prevents a program from accessing memory outside its segments. Protection bits prevent code segments from being written, stack from being executed, etc.

What is the advantage of combining segmentation with paging?

Seg-Paged combines the logical structure of segments (each segment corresponds to a program section) with the fragmentation-free management of paging. Each segment is divided into pages. Address translation: virtual → (segment table) → linear address → (page tables) → physical. Used in x86-64 architecture. Provides flexible protection, sharing, and efficient memory use.

Explain the difference between a segmentation fault and a page fault.

A segmentation fault occurs when a program accesses memory outside its valid segment (offset > limit) or violates protection (writing to read-only segment). It is a programming error that typically kills the process. A page fault occurs when a valid page is not in physical memory — the OS handles it transparently by loading the page from disk, and the program continues execution unaware.