Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong><em>New answer:</em></strong></p> <p>I've already encounter this problem some time ago and the only way I found to update the GDT with MASM inline assembly is to use a far return instruction, instead of the far jump instruction. </p> <pre><code>struct gdt_entry gdt[3]; struct gdt_ptr gp; void gdt_flush(){ __asm{ lgdt [gp] mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ; push the address on the stack push 0x08 mov eax, offset flush2 push eax ; ret use the previous pushed address _emit 0xCB ; far return flush2: ;ret } } </code></pre> <p>As far as I remember, there are two problems:</p> <ul> <li>the 32 bits MASM inline assembly cannot compile far instructions, so you have to emit the opcode.</li> <li>the <code>jmp</code> instruction does not do the right stuff and you should use instead the <code>ret</code> instruction to jump to the next line of code.</li> </ul> <p>Also, don't call the ret instruction from the inline assembly, otherwise you'll skip the epilog code that the compiler puts at the end of the function to clean the stack.</p> <hr> <p><strong><em>My first answer below:</em></strong></p> <p>Maybe your GDT descriptor (gp) is badly initialized. </p> <p>When you the jump instruction is executed, the processor try to switch to protected mode and the GDT is then required. If the GDT is not set correctly, it crashed.</p> <p>The first 16 bits of gp are the size of the gdt (here 3*8 = 24 bytes) and the following 32 bytes are the address of the gdt (here &amp;gdt[0]).</p> <p>Also, make sure the ds register is null before calling lgdt: this register is used by the instruction.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload