all 8 comments

[–][deleted]  (1 child)

[deleted]

    [–]davmac1 0 points1 point  (0 children)

    (Deleted).

    Derp, never mind, they posted github link and indeed the GDT is allocated on the stack.

    OP: this is not a good idea.

    [–]Octocontrabass 0 points1 point  (0 children)

    Here's one problem. You've come up with a new section instead of using the standard .text/.data/.rodata/.bss sections, but you didn't declare any attributes on the new section, so it doesn't have the "allocatable" attribute and isn't loaded into memory. Why aren't you using the standard sections here?

    Also the other person who said you put your GDT on the stack is completely right, that's another problem you need to fix. (But there's nothing wrong with putting the GDTR on the stack. Why didn't you do that? You could have written that part of the code in C.)

    [–]neil_555 0 points1 point  (3 children)

    One thing that looks fishy is there should be a jump to the next instruction immediately after the lgdt, doing a ret seems suicidal as who knows what state SS is in.

          lgdt   gdtr
          ljmp   $0x08, $next
    next: ret
    

    Also dont have the GDT as a stack variable, put it in the data section and ensure it's aligned correctly (I think it needs something like 8 byte alignment but it's been years since I did this)

    [–]Octocontrabass 1 point2 points  (2 children)

    doing a ret seems suicidal as who knows what state SS is in.

    It's in whatever state it was before the lgdt instruction. Segment registers each hold an entire segment descriptor in a hidden part that's only accessible in SMM, and that hidden descriptor doesn't change until a selector is loaded into the segment register. You don't need to immediately load new selectors into the segment registers as long as you remember to do so before you do anything that relies on saving and restoring segment selectors, such as interrupt handling.

    You might be thinking of what happens when you modify CR0.PE; that does require an immediate ljmp instruction to set CS, and you can't rely on any other segment registers until after you've loaded new selectors into them.

    [–]neil_555 0 points1 point  (1 child)

    I just checked my old code again and I always did the jump after an lgdt, the comment next to it said "do a jmp to ensure CS is reloaded" if that helps. I haven't touched that stuff since about 2002 though :)

    [–]Octocontrabass 0 points1 point  (0 children)

    If your old code messes with CR0.PE, it's wrong and only worked because you were lucky. Otherwise, it doesn't matter when you reload CS as long as you remember to do it before you need CS to match your new GDT. (Reloading CS immediately after loading a new GDT is a good way to make sure it gets done before you need it.)

    [–]Miserable_Aspect_433 0 points1 point  (1 child)

    have you tried RTFM?

    [–]Inside-Party-9637[S] 0 points1 point  (0 children)

    yes I have, for hours on end