What exactly are null segment selectors?

jj1984

Member
Hello,

From Intel's manual about IA-32e mode:

On privilege level changes, stack segment selectors are not read from the TSS. Instead, they are set to NULL.

What does it mean to set a segment selector to null?

Does it mean that you set the segment selector in the segment register to point to the first descriptor in the GDT, the null descriptor?

Or, does it mean that you put some special value in the segment register?

If so, what is this special value?

Earlier in the manual, it says this about loading segment registers with selectors in protected mode:

Loading the CS or SS register with a null segment selector causes a general-protection exception (#GP) to be generated.

So, how can we do both?

How can we put a null segment selector in the SS register if doing so will throw an exception?

Is the above restriction lifted in IA-32e mode?

Thanks.
 

Cromewell

Administrator
Staff member
Should all be in the manual.
Intel Manual vol. 3A @ Segemnt Selectors (p3-7):
The first entry of the GDT is not used by the processor. A segment selector that points to this entry of the GDT (that is, a segment selector with an index of 0 and the TI flag set to 0) is used as a “null segment selector.” The processor does not generate an exception when a segment register (other than the CS or SS registers) is loaded with a null selector. It does, however, generate an exception when a segment register holding a null selector is used to access memory. A null selector can be used to initialize unused segment registers. Loading the CS or SS register with a null segment selector causes a general-protection exception (#GP) to be generated.
 

jj1984

Member
Should all be in the manual.
Thanks; though, I'm familiar with the passage.

The passage implies that a null stack segment selector contains 0 as it points to the 0th descriptor in the GDT.

But, this is the part that confuses me:

Loading the CS or SS register with a null segment selector causes a general-protection exception (#GP) to be generated.

In x86-64 mode, how can we load the SS register with 0 without throwing an exception?
 

Cromewell

Administrator
Staff member
Why would you want to? Think about what SS points to. If I say the stack starts at 0 bad things are going to happen.
 

jj1984

Member
Why would you want to?
Well, according to the manual, in IA-32e mode (x86-64 mode) when you change privilege levels, the SS register is set to null.

That is, you don't load the SS register with the stack segment selector for the new privilege level that is stored in the task segment.

In old school 32-bit protected mode you would do things that way; you would look into the current task segment and load the segment selector into SS that way.

However, I do believe that the whole task switching mechanism is disabled in x86-64 mode.

This is why I'm asking about setting the SS register to null and what that actually means.

It makes sense that putting 0 into the SS register and having it point to the null descriptor in the GDT would constitute setting the register to null.

But, then there's the exception that is supposed to be thrown when you do so.

This is why I'm confused.

If I say the stack starts at 0 bad things are going to happen.
There are a number of issues here:

First, in x86-64 mode, the bases of the segments whose selectors are stored in the CS, SS, DS, and ES segment registers are forced to 0.

Also, in protected mode, you can set all descriptors to have a base of 0 if you want, thereby creating a flat linear space.

So, there's no inherent problem with having the stack segment start at zero.

Second, having the stack segment start at zero is not the same as having the stack pointer set at zero.

I think that that's what you were thinking subconsciously.

You can have the stack segment start at zero and have the stack pointer (the "top" of the stack) point elsewhere.

Lastly, there's a difference between where a segment starts, its base, and what's in the segment selector register for that segment.

Just because X is in the selector register, doesn't mean that that segment starts at X.

That said, my question stands:

When in x86-64 mode and changing privilege levels, the SS segment selector register is set to null.

What number is null?

What is actually put into the SS register in this situation?
 
Last edited:

Cromewell

Administrator
Staff member
Well, according to the manual, in IA-32e mode (x86-64 mode) when you change privilege levels, the SS register is set to null.
The problem with looking at long (x86-64) mode is that the processor doesn't do runtime checking on null segment selectors, and you don't get GP faults when you try to load null segments.
 

jj1984

Member
The problem with looking at long (x86-64) mode is that the processor doesn't do runtime checking on null segment selectors, and you don't get GP faults when you try to load null segments.
So, you're saying that in x86-64 mode the restriction that loading the SS register with the null selector throws an exception is lifted?

If so, then I assume setting the SS register to null means putting 0 in the SS register so that it points to the 0th descriptor in the GDT, the null descriptor.

Yes?
 

Cromewell

Administrator
Staff member
Right, since x86-64 doesn't use segmentation. When running in 64-bit mode CS, SS, DS, and ES forced to 0. FS and GS can have nonzero values and are typically used by the OS.
 
Top