0

I'm trying to fully understand how paging works in the x86 architecture when segmentation is also enabled.

I have a couple of questions:

  1. Does paging divide the logical memory (the selector + offset space, 14+32 bits) or the segments?

  2. Why does the linear address have a direct meaning in physical memory when paging is disabled, but loses that meaning (becoming "virtual") when paging is enabled?

I understand that segmentation translates logical addresses into linear ones, and then paging translates linear addresses into physical ones — but I’m not sure what the "space" being divided into pages actually is, and why the linear address' meaning changes depending on whether paging is active or not.

1 Answer 1

1

Paging divides linear address-space into 4K pages.

Generating a linear address from a logical seg:off works the same (adding the segment_base of the selected segment to the offset) regardless of whether the linear address will be used directly as a physical address (paging disabled) or treated as virtual and translated by the page tables (paging enabled).
The term "linear address" exists because of segmentation, not paging, and dates back to 8086. (Paging was new for x86 in 386).

The whole point of enabling paging is changing the meaning of some kind of address from physical to virtual, and in x86 those addresses happen to have another name that still applies even with paging enabled. In other ISAs like ARM without segmentation, you'd just say "addresses change meaning from physical to virtual when paging is enabled". In x86 we're also just adding an extra step at the end of address-generation; what would be physical addresses without paging are now virtual.


Segmentation base+offset is done before paging as you say. Note that segment bases are 32-bit in 32-bit protected mode; the selector itself is 14 bits (plus the bottom 2 bits being ring0-3 privilege level), but changing the GDT/LDT and reloading a segment with a selector is possible. Or of course you could just use large segments to cover more of 32-bit linear address-space.

Mainstream OSes don't really use segmentation except for thread-local storage via a non-zero FS or GS base; they set all other segments to base=0 / limit=unlimited, so linear=offset and all 32-bit pointers are linear virtual addresses. So functions that accept pointers can just take a simple 32-bit pointer with no segment selector, and work on pointers to stack memory (normally accessed via SS), static storage and memory-mapped files (normally via DS or ES), or machine code (normally via CS).
(64-bit mode of x86-64 makes this flat memory model the only option, only allowing non-zero FS and GS bases for TLS.)

Sign up to request clarification or add additional context in comments.

3 Comments

Now that you mention the selector size I have another question. I've read that a 14-bit selector allows for 2^14 segments, and if each segment can be 4GB, that implies a total addressable memory of 64TB. However, I understand that different selector:offset combinations can point to the same linear address. This suggests that 64TB isn't the true size of the virtual address space. So what is the actual maximum size of the virtual address space?
Segments have to fully overlap if they're all 4GiB. Linear / virtual address-space is 4GB whether paging is enabled or not. Segment bases are 32-bit, and are simply added to the offset, with truncation to 32-bit even with paging disabled I'm pretty sure. Certainly with paging enabled, since the page-table structures (a radix tree with implicit indexing) can definitely only translate 32-bit virtual addresses. (With PAE enabled, translate to wider physical addresses, so you can run multiple processes that each use 4GiB of physical memory, but each is only 4GiB).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.