X86 Memory Segmentation - Practices

Practices

Logical addresses can be explicitly specified in x86 assembly language, e.g. (AT&T syntax):

movl $42, %fs:(%eax) ; Equivalent to M<-42) in RTL

However, segment registers are usually used implicitly.

  • All CPU instructions are implicitly fetched from the code segment specified by the segment selector held in the CS register.
  • Most memory references come from the data segment specified by the segment selector held in the DS register. These may also come from the extra segment specified by the segment selector held in the ES register, if a segment-override prefix precedes the instruction that makes the memory reference. Most, but not all, instructions that use DS by default will accept an ES override prefix.
  • Processor stack references, either implicitly (e.g. push and pop instructions) or explicitly (memory accesses using the (E)SP or (E)BP registers) use the stack segment specified by the segment selector held in the SS register.
  • String instructions (e.g. stos, movs), along with data segment, also use the extra segment specified by the segment selector held in the ES register.

Segmentation cannot be turned off on x86-32 processors (this is true for 64-bit mode as well, but beyond the scope of discussion), so many 32-bit operating systems simulate a flat memory model by setting all segments' bases to 0 in order to make segmentation neutral to programs. For instance, the Linux kernel sets up only 4 general purpose 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. (This, of course, refers to 80386 and later processors, as the earlier x86 processors do not have a paging unit.)

Current Linux also uses GS to point to thread-local storage.

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, in protected mode, code may always modify all segment registers except CS (the code segment selector). 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) instructions. In real mode, code may also modify the CS register by making a far jump (or using an undocumented POP CS instruction on the 8086 or 8088)). Of course, in real mode, there are no privilege levels; all programs have absolute unchecked access to all of memory and all CPU instructions.

For more information about segmentation, see the IA-32 manuals freely available on the AMD or Intel websites.

Read more about this topic:  X86 Memory Segmentation

Famous quotes containing the word practices:

    Money made through dishonest practices will not last long.
    Chinese proverb.

    They that have grown old in a single state are generally found to be morose, fretful and captious; tenacious of their own practices and maxims; soon offended by contradiction or negligence; and impatient of any association but with those that will watch their nod, and submit themselves to unlimited authority.
    Samuel Johnson (1709–1784)

    To learn a vocation, you also have to learn the frauds it practices and the promises it breaks.
    Mason Cooley (b. 1927)