What exactly are null segment selectors?

Discussion in 'General Software' started by jj1984, Feb 7, 2017.

  1. jj1984

    jj1984 Member

    Messages:
    116
    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.
     
  2. Cromewell

    Cromewell Administrator Staff Member

    Messages:
    15,447
    Should all be in the manual.
     
    johnb35 likes this.
  3. jj1984

    jj1984 Member

    Messages:
    116
    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?
     
  4. Cromewell

    Cromewell Administrator Staff Member

    Messages:
    15,447
    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.
     
  5. jj1984

    jj1984 Member

    Messages:
    116
    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.

    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: Feb 9, 2017
  6. Cromewell

    Cromewell Administrator Staff Member

    Messages:
    15,447
    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.
     
  7. jj1984

    jj1984 Member

    Messages:
    116
    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?
     
  8. Cromewell

    Cromewell Administrator Staff Member

    Messages:
    15,447
    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.
     
  9. jj1984

    jj1984 Member

    Messages:
    116
    OK. Thanks.
     

Share This Page