Segmentation
Chapter Seventy-Three
Syllabus topic Module 2, "Memory Management - Segmentation"
Pages 286 to 289 of 452
In one line
Divide a program into its natural pieces, give each piece its own base and limit, and let each grow independently.
Why a programmer does not think in one address space
A program is not a single run of bytes to the person who wrote it. It is a main routine, some functions, a stack, a symbol table, some arrays. Each of those is a separate thing with a separate length, and the programmer refers to the fifth element of an array, not to byte 26,472 of the program.
Contiguous allocation forces all of it into one block with one base and one limit, and then a growing stack runs into a growing heap. Segmentation is the scheme that keeps the pieces apart, and that is the one sentence answer to why it exists.
| A program's segments, typically | Holds |
|---|---|
| the code | the instructions |
| global variables | the data section |
| the heap | memory asked for while running |
| the stack, one per thread | call frames |
| the standard library | shared with every other process |
The address
A logical address under segmentation is two parts, and the program supplies both.
logical address = < segment number, offset >
On a machine where the address is one word, the segment number is the top bits and the offset the bottom bits, and the compiler produces both. On the Intel architecture it was two separate registers, a segment selector and an offset, which is where the design comes from.
The segment table
One entry per segment, and every entry is two numbers.
| Field | Means |
|---|---|
| base | the physical address where the segment starts |
| limit | the length of the segment |
Two registers point at the table itself: the segment table base register, which says where the table is, and the segment table length register, which says how many entries it has.
The limit is a length, not a top address, exactly as in Chapter sixty six, and it is the same off by one trap.
The translation, in three steps
Given a logical address of segment s and offset d:
- Is s a legal segment number? If s is not less than the segment table length register,
trap.
- Is d within the segment? If d is not less than limit[s], trap: this is an
addressing error.
- The physical address is base[s] + d.
Step 2 is the protection, and it is per segment. That is a real gain over one base and limit for the whole process: a stack overrunning its own segment is caught immediately, rather than quietly writing over the heap.
Worked, with every case
A process with five segments.
| Segment | What it holds | base | limit |
|---|---|---|---|
| 0 | the code | 1400 | 1000 |
| 1 | the symbol table | 6300 | 400 |
| 2 | a string table | 4300 | 400 |
| 3 | the main routine | 3200 | 1100 |
| 4 | the stack | 4700 | 1000 |
Segmentation
Now translate eight addresses. Each line is base plus offset, after the limit test.
| Logical address | Limit test | Physical address |
|---|---|---|
| segment 0, offset 0 | 0 below 1000 | 1400 + 0 = 1400 |
| segment 0, offset 999 | 999 below 1000 | 1400 + 999 = 2399 |
| segment 0, offset 1000 | 1000 is not below 1000 | trap |
| segment 1, offset 53 | 53 below 400 | 6300 + 53 = 6353 |
| segment 2, offset 399 | 399 below 400 | 4300 + 399 = 4699 |
| segment 2, offset 400 | 400 is not below 400 | trap |
| segment 3, offset 852 | 852 below 1100 | 3200 + 852 = 4052 |
| segment 4, offset 1222 | 1222 is not below 1000 | trap |
Three of the eight trap, and two of them trap on an offset exactly equal to the limit. The test is strictly less than, and a question will include exactly that case.
Notice the segments are not in order in physical memory: segment 1 is at 6300, above segment 4 at 4700. The operating system put each segment wherever there was a hole big enough, which is the freedom segmentation buys and the fragmentation it costs.
What segmentation is good at
Three things, and each is a real advantage over one block per process.
- Each segment grows on its own. The stack growing does not threaten the heap: they are
different segments with different bases, and only the stack's own limit constrains it.
- Protection is per segment, and can differ per segment. The code segment can be marked read
only and execute, the data segment read and write and not execute. A program that jumps into its data is caught. One base and limit for the whole process cannot express that at all.
- Sharing is natural. Two processes running the same program can have segment 0 entries with
the same base, so one copy of the code serves both. That is Chapter fourteen of Module 1's shared text, implemented.
The third has a catch worth knowing: a shared code segment must be the same segment number in every process that shares it, because a jump inside the code contains a segment number. If it is segment 0 in one process and segment 2 in another, the jump goes to the wrong place.
What segmentation is bad at, and why paging replaced it
Segments are variable sized, so segmentation has external fragmentation, exactly as Chapter seventy's variable partitions do, and for the same reason: a hole must be found that is big enough for the whole segment.
| Segmentation | Variable partitions | |
|---|---|---|
| Allocation unit | one segment | one whole process |
| Number of units per process | several | one |
| External fragmentation | yes | yes |
| Internal fragmentation | none | a little |
Segmentation
Segmentation is better than one block per process, because the pieces are smaller and a smaller piece is easier to place. It is not a cure, because the pieces are still variable in size. Paging's insight is to make every piece the same size, and that removes external fragmentation entirely.
Which is why real machines did both: segmentation with paging, where each segment is itself paged. The Intel architecture worked exactly that way, and modern systems have dropped the segmentation half and kept the paging.
Distinctions that carry marks
| Segmentation | Paging (Chapter seventy four) | |
|---|---|---|
| Pieces are | variable sized, and meaningful to the programmer | fixed sized, and meaningless to the programmer |
| The address is | segment number and offset, supplied by the program | page number and offset, computed from one number |
| External fragmentation | yes | none |
| Internal fragmentation | none | half a page per process |
| The programmer is aware of it | yes | no |
| Table entry holds | base and limit | a frame number, and no limit |
The last two rows are the deepest difference and a question about it wants them. A segment has a limit because segments differ in size; a page needs none because every page is full. And the programmer chooses the segments, while pages are cut by the hardware wherever the page size falls.
| Segment table | The relocation register of Chapter sixty six | |
|---|---|---|
| Entries | one per segment | one |
| Protection | per segment, and can differ | one rule for the whole process |
| A growing stack | constrained only by its own limit | constrained by the whole process's limit |
What it does not mean
A segment is not a page. A segment is a logical piece of a program, of whatever size that piece is. A page is a fixed sized piece of an address space with no meaning at all.
Segmentation is not obsolete as an idea. Every program still has a code segment, a data segment and a stack, and the permissions on them are still different. What is obsolete is implementing those divisions with a segment table rather than with page permissions.
The segment number is not computed by the hardware. The program supplies it. That is the property that makes segmentation visible to the programmer and paging invisible.
Per segment limits do not remove the need for a stack limit. They give the stack its own limit, which is a much better thing than sharing the process's.
Quick revision
- Segmentation divides a program into its natural, variable sized pieces: code, data,
heap, stack, library.
- A logical address is a segment number and an offset, and the program supplies both.
- Each segment table entry holds a base and a limit, where the limit is a length.
Segmentation
Two registers give the table's position and its length.
- Translation: check the segment number against the table length; check the offset is
strictly less than the limit, or trap with an addressing error; then the physical address is base plus offset.
- Gains: each segment grows independently, protection is per segment and can differ, and
sharing one segment between processes is natural.
- A shared segment must have the same segment number in every process, because a jump carries
one.
- Segments are variable sized, so segmentation has external fragmentation. That is why
paging, whose pieces are all the same size, replaced it.
Test yourself
- What is a segment, and what does a logical address look like? A logical, variable sized
piece of a program such as the code, the stack or an array. The address is a segment number together with an offset within that segment, both supplied by the program.
- What does each segment table entry hold? A base, the physical address where the segment
begins, and a limit, the length of the segment.
- Give the translation steps. Check the segment number is less than the segment table length
register; check the offset is strictly less than the segment's limit, trapping with an addressing error if not; then add the base to the offset.
- Segment 2 has base 4300 and limit 400. Translate offsets 399 and 400. 399 is below the
limit, so 4300 + 399 = 4699. 400 is not strictly below 400, so it traps.
- Give three advantages of segmentation over one block per process. Each segment grows
independently, so a growing stack cannot damage the heap; protection is per segment and can differ, so code can be read only and data non executable; and one segment can be shared between processes with the same base in each.
- What must be true of a shared segment's number, and why? It must be the same number in
every process that shares it, because a jump within the code carries a segment number with it.
- Why did paging replace segmentation? Segments are variable sized, so a hole big enough for
a whole segment must be found and external fragmentation results. Paging makes every piece the same size, so any free frame fits any page and external fragmentation disappears.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself, or the past papers, for the same subject.