Not physical, if page translation is enabled. And it doesn't really split anything.
MuchLearning wrote:into segments which the processor then references through special registers (cs, ds, ss, ...). What I don't understand is how this works with paging. Is the GDT set up before paging is enabled or are they two separate approaches to memory segmentation? If they are used in unison, after paging is enabled aren't the addresses to the different segments incorrect?
; // I'll be talking about the 80386 unless otherwise specified.
If page translation is disabled, a segment is basically a window through which you can access physical memory.
So, for example, the mov eax, [es:ebx] instruction will use the value of the es register (AKA segment selector) as an index into the GDT (or LDT) to specify one of the many windows that the GDT (or LDT) can describe (up to 8192 windows per table AFAIR). So it gets the start address of the window (AKA segment base address) and the window size from the table. It then counts ebx bytes (AKA segment offset) up from the start address and gets the physical address of where to read from. It also checks that the read at this address doesn't go outside of the window.
The windows (er, segments) are completely independent and can start anywhere and their size can be almost anything (see segment size granularity), from 1 byte to 4GB. They can overlap or coincide if desired.
Segmentation is always present. You can't turn it off, but you can disempower it by using segments of the largest size possible and starting at address 0, that is, viewing all of the memory through the windows.
If page translation is enabled, you have the same thing as above, but the address that you get by using the segment selector and segment offset (and going through the GDT/LDT) is not the final physical one. It's a virtual (AKA linear) one, which undergoes conversion into the physical one according to the page tables.
IOW, when page translation is enabled, segmentation provides windowed view of virtual rather than physical memory.
Because of this virtual to physical conversion, at the points where you enable (or disable) page translation, the instruction that enables/disables it needs to have its virtual and physical addresses the same (AKA identity or 1:1 mapping). Otherwise the CPU will go fetching the following instructions from the wrong place. (It's likely a bit more nuanced, I haven't touched this bit for a long time)
When page translation is enabled, for most things segmentation is useless and therefore segments of 4GB size are in use.
However, there are a few common special uses of segmentation even with page translation is on.
One is thread-local storage (TLS).
Another is non-executable memory. You can make your code segment precisely of the code size of your program and eliminate erroneous (or malicious) execution of data. However, there are ways to go around this, namely return-oriented programming (ROP).
Memory can be made non-executable through page tables on modern CPUs as well, but originally only segmentation provided a way for doing this.
Qs?