MEMORY SEGMENT
On the Intel x86 architecture, a 'memory segment' is the portion of memory which may be addressed by a single index register without changing a 16-bit 'segment selector'. In real mode or V86 mode, a segment is always 64 kilobytes in size (using 16-bit index registers). In protected mode, a segment can have variable length.

In 16-bit real mode, enabling applications to make use of multiple memory segments (in order to access more memory than available in any one 64K-segment) was quite complex, but was viewed as a necessary evil for all but the smallest tools (which could do with less memory). The root of the problem was that no appropriate address-arithmetic instructions suitable for flat addressing of the entire memory range were available. Flat addressing is possible by applying multiple instructions, which however leads to slower programs.
In real mode, the 16-bit segment selector was interpreted as the first 16 bits of a linear 20-bit address, with the remaining four being all zeros. The segment selector is always added with a 16-bit offset to yield a linear address. For instance, the segmented address 0x06EF:0x1234 has a segment selector of 0x06EF, which corresponds to the 20-bit linear address 0x06EF0. To this we add the offset, yielding the linear address 0x06EF0 + 0x1234 = 0x08124 (cf. hexadecimal).
A single linear address can be mapped to many segmented addresses. For instance, the linear address above (0x08124) can have the segmented addresses 0x06EF:0x1234, 0x0812:0x0004 and 0x0000:0x8124 (and many more). This could be confusing to programmers accustomed to unique addressing schemes.
The effective 20-bit address space of real mode limited the addressable memory to 220 bytes, or 1,048,576 bytes.

In protected mode, segmentation is used as a virtual memory mechanism, providing memory isolation and contiguous addressing of non-contiguous physical memory.
On the 386 and later, programs issue logical (48-bit) addresses which go through the segmentation unit to be checked and translated into linear 32-bit addresses, before being sent to the paging unit (if enabled) which ultimately translates them into physical addresses (also 32-bit on the 386, but can be larger on more modern processors which support Physical Address Extension).
A logical address consists of a 16-bit segment selector and a 32-bit or 16-bit offset (in a 16-bit segmented address space the middle 16-bit are 0, while in a 32-bit flat address space, the top 16-bit is not 0 (in fact it cannot be 0, since this means a null selector), but are the same for every such references (except code, because a segment cannot be readable, writable and executable at the same time)).
The segment selector must be located in one of the segment registers: 'CS', 'DS', 'SS', 'ES', 'FS', 'GS' (CodeSegment, DataSegment, StackSegment, ExtraSegment). That selector consists of a 2-bit Requested Privilege Level (RPL, where the lowest number has the highest privilege), a 1-bit Table Indicator (TI), and a 13-bit index.
The processor access by the appropriate amount (times 8 since segment descriptors are 8 bytes) the GDT (Global Descriptor Table) if TI=0, or the LDT (Local Descriptor Table) if TI=1. It then performs the following privilege check:
DPL < max(CPL, RPL)
where CPL is the current privilege level (lower 2 bits in CS), RPL is the requested privilege level from the segment selector, and DPL is the descriptor privilege level of the segment (found in the descriptor). If the equation is true, the processor generates a general protection fault (#GP). Otherwise, address translation continues. Actually this privilege check is done only once, when the segment register is loaded since segment descriptors are cached in hidden parts of the segment registers. The processor then takes the 32-bit or 16-bit offset and compares it against the segment limit specified in the segment descriptor. If it is larger, a GP fault is generated. Otherwise, the processor adds the segment base (32-bit or 24-bit, specified in descriptor) to the offset and this creates a linear address.
Logical addresses can be explicitly specified in x86 assembler language, e.g. (AT&T syntax):
movl $42, %fs:(%eax) ; Equivalent to M[fs:eax]<-42) in RTL
Usually, however, implied segments are used. All instruction fetches come from the code segment in the CS register. Most memory references come from data segment in the DS register. Processor stack references, either implicitly (e.g. 'push' and 'pop' instructions) or explicitly (memory accesses using the ESP or (E)BP registers) use the stack segment in the SS register. Finally, string instructions (e.g. 'stos', 'movs') also use the extra segment ES.
Segmentation cannot be turned off on x86 processors, so many operating systems use a flat memory model to make segmentation unnoticeable to programs. For instance, the Linux kernel sets up only 4 segments:
★ __KERNEL_CS (Kernel code segment, base=0, limit=4GB, DPL=0)
★ __KERNEL_DS (Kernel data segment, base=0, limit=4GB, DPL=0)
★ __USER_CS (User code segment, base=0, limit=4GB, DPL=3)
★ __USER_DS (User data segment, base=0, limit=4GB, DPL=3)
Since the base is set to 0 in all cases and the limit 4 GiB, the segmentation unit does not affect the addresses the program issues before they arrive at the paging unit.
Segments can be defined to be either code, data, or system segments. Additional permission bits are present to make segments read only, read/write, execute, etc.
Note that code may always modify all segment registers ''except'' CS (the code segment). This is because the current privilege level (CPL) of the processor is stored in the lower 2 bits of the CS register. The only way to raise the processor privilege level (and reload CS) is through the 'lcall' (far call) and 'int' (interrupt) instructions. Similarly, the only way to lower the privilege level (and reload CS) is through 'lret' (far return) and 'iret' (interrupt return).
For more about segmentation, see the IA-32 manuals freely available on the AMD or Intel websites.
★ Memory model
★ THE multiprogramming system
★ Home of the IA-32 Intel Architecture Software Developer's Manual
★ The Segment:Offset Addressing Scheme
| Contents |
| Real mode |
| Protected mode |
| Detailed Segmentation Unit Workflow |
| Practices |
| See also |
| External links |
Real mode
Three segments in real mode memory (click on image to enlarge). Note the overlap between segment 2 and segment 3; the bytes in the turquoise area can be using from both segment selectors.
In 16-bit real mode, enabling applications to make use of multiple memory segments (in order to access more memory than available in any one 64K-segment) was quite complex, but was viewed as a necessary evil for all but the smallest tools (which could do with less memory). The root of the problem was that no appropriate address-arithmetic instructions suitable for flat addressing of the entire memory range were available. Flat addressing is possible by applying multiple instructions, which however leads to slower programs.
In real mode, the 16-bit segment selector was interpreted as the first 16 bits of a linear 20-bit address, with the remaining four being all zeros. The segment selector is always added with a 16-bit offset to yield a linear address. For instance, the segmented address 0x06EF:0x1234 has a segment selector of 0x06EF, which corresponds to the 20-bit linear address 0x06EF0. To this we add the offset, yielding the linear address 0x06EF0 + 0x1234 = 0x08124 (cf. hexadecimal).
A single linear address can be mapped to many segmented addresses. For instance, the linear address above (0x08124) can have the segmented addresses 0x06EF:0x1234, 0x0812:0x0004 and 0x0000:0x8124 (and many more). This could be confusing to programmers accustomed to unique addressing schemes.
The effective 20-bit address space of real mode limited the addressable memory to 220 bytes, or 1,048,576 bytes.
Protected mode
Three segments in protected mode memory (click on image to enlarge), with the 'local descriptor table'.
In protected mode, segmentation is used as a virtual memory mechanism, providing memory isolation and contiguous addressing of non-contiguous physical memory.
On the 386 and later, programs issue logical (48-bit) addresses which go through the segmentation unit to be checked and translated into linear 32-bit addresses, before being sent to the paging unit (if enabled) which ultimately translates them into physical addresses (also 32-bit on the 386, but can be larger on more modern processors which support Physical Address Extension).
Detailed Segmentation Unit Workflow
A logical address consists of a 16-bit segment selector and a 32-bit or 16-bit offset (in a 16-bit segmented address space the middle 16-bit are 0, while in a 32-bit flat address space, the top 16-bit is not 0 (in fact it cannot be 0, since this means a null selector), but are the same for every such references (except code, because a segment cannot be readable, writable and executable at the same time)).
The segment selector must be located in one of the segment registers: 'CS', 'DS', 'SS', 'ES', 'FS', 'GS' (CodeSegment, DataSegment, StackSegment, ExtraSegment). That selector consists of a 2-bit Requested Privilege Level (RPL, where the lowest number has the highest privilege), a 1-bit Table Indicator (TI), and a 13-bit index.
The processor access by the appropriate amount (times 8 since segment descriptors are 8 bytes) the GDT (Global Descriptor Table) if TI=0, or the LDT (Local Descriptor Table) if TI=1. It then performs the following privilege check:
DPL < max(CPL, RPL)
where CPL is the current privilege level (lower 2 bits in CS), RPL is the requested privilege level from the segment selector, and DPL is the descriptor privilege level of the segment (found in the descriptor). If the equation is true, the processor generates a general protection fault (#GP). Otherwise, address translation continues. Actually this privilege check is done only once, when the segment register is loaded since segment descriptors are cached in hidden parts of the segment registers. The processor then takes the 32-bit or 16-bit offset and compares it against the segment limit specified in the segment descriptor. If it is larger, a GP fault is generated. Otherwise, the processor adds the segment base (32-bit or 24-bit, specified in descriptor) to the offset and this creates a linear address.
Practices
Logical addresses can be explicitly specified in x86 assembler language, e.g. (AT&T syntax):
movl $42, %fs:(%eax) ; Equivalent to M[fs:eax]<-42) in RTL
Usually, however, implied segments are used. All instruction fetches come from the code segment in the CS register. Most memory references come from data segment in the DS register. Processor stack references, either implicitly (e.g. 'push' and 'pop' instructions) or explicitly (memory accesses using the ESP or (E)BP registers) use the stack segment in the SS register. Finally, string instructions (e.g. 'stos', 'movs') also use the extra segment ES.
Segmentation cannot be turned off on x86 processors, so many operating systems use a flat memory model to make segmentation unnoticeable to programs. For instance, the Linux kernel sets up only 4 segments:
★ __KERNEL_CS (Kernel code segment, base=0, limit=4GB, DPL=0)
★ __KERNEL_DS (Kernel data segment, base=0, limit=4GB, DPL=0)
★ __USER_CS (User code segment, base=0, limit=4GB, DPL=3)
★ __USER_DS (User data segment, base=0, limit=4GB, DPL=3)
Since the base is set to 0 in all cases and the limit 4 GiB, the segmentation unit does not affect the addresses the program issues before they arrive at the paging unit.
Segments can be defined to be either code, data, or system segments. Additional permission bits are present to make segments read only, read/write, execute, etc.
Note that code may always modify all segment registers ''except'' CS (the code segment). This is because the current privilege level (CPL) of the processor is stored in the lower 2 bits of the CS register. The only way to raise the processor privilege level (and reload CS) is through the 'lcall' (far call) and 'int' (interrupt) instructions. Similarly, the only way to lower the privilege level (and reload CS) is through 'lret' (far return) and 'iret' (interrupt return).
For more about segmentation, see the IA-32 manuals freely available on the AMD or Intel websites.
See also
★ Memory model
★ THE multiprogramming system
External links
★ Home of the IA-32 Intel Architecture Software Developer's Manual
★ The Segment:Offset Addressing Scheme
This article provided by Wikipedia. To edit the contents of this article, click here for original source.
psst.. try this: add to faves

العربية
中国
Français
Deutsch
Ελληνική
हिन्दी
Italiano
日本語
Português
Русский
Español