Note that there are some explanatory texts on larger screens.

plurals
  1. POAssembler jump in Protected Mode with GDT
    text
    copied!<p>I am currently playing around with x86 Assember in order to sharpen my low-level programming skills. Currently, I am facing a little problem with the addressing scheme in 32-Bit Protected Mode.</p> <p>The situation is the following:</p> <p>I have a Program loaded at 0x7e0 which switches the CPU to Protected Mode and jumps to the according label in the code:</p> <pre><code>[...] code to switch CPU in Protected Mode [...] jmp ProtectedMode [...] bits 32 ProtectedMode: .halt: hlt jmp .halt </code></pre> <p>This works absolutely fine so far. The "jmp ProtectedMode" works without a explicit far jump to clear the prefetch queue - since this program is loaded with offset 0 (org 0 at the beginning) - causing the code segment pointing to the right location.</p> <p>My current problem now is, that within the "ProtectedMode" label I want to jump to an other program which is loaded at 0x8000 (I checked this with a memory dump, the loading function did work properly and the program is loaded correctly to 0x8000).</p> <p>Since the CPU is now in ProtectedMode and not RealMode anymore, the addressing schema is different. ProtectedMode uses descriptor selectors to lookup a base address and a limit in a descriptor table to add the given offset and retrieve the physical address (as I understood). Therefore, it was necessary to install a GDT before entering ProtectedMode.</p> <p>Mine is looking like the following:</p> <pre><code>%ifndef __GDT_INC_INCLUDED__ %define __GDT_INC_INCLUDED__ ;********************************* ;* Global Descriptor Table (GDT) * ;********************************* NULL_DESC: dd 0 ; null descriptor dd 0 CODE_DESC: dw 0xFFFF ; limit low dw 0 ; base low db 0 ; base middle db 10011010b ; access db 11001111b ; granularity db 0 ; base high DATA_DESC: dw 0xFFFF ; data descriptor dw 0 ; limit low db 0 ; base low db 10010010b ; access db 11001111b ; granularity db 0 ; base high gdtr: Limit dw 24 ; length of GDT Base dd NULL_DESC ; base of GDT %endif ;__GDT_INC_INCLUDED__ </code></pre> <p>and is loaded to the GDT register via</p> <pre><code>lgdt [gdtr] </code></pre> <p>What I did not understand so far is, how do I now jump to the physical address 0x8000 in ProtectedMode using the GDT?</p> <p>My first thoughts were to select the Code Descriptor (CODE_DESC) which should point to 0x7e00 (were the current program is loaded) and use the offset that is necessary to get to 0x8000 (512 bytes), resulting in the jump instruction:</p> <pre><code>jmp CODE_DESC:0x200 </code></pre> <p>But this does not work. </p> <pre><code>jmp 0x7e0:0x200 </code></pre> <p>does not work either...</p> <p>Do you have any idea what I am missing here? Maybe I did not understand something essential within the 32-Bit ProtectedMode addressing scheme and the usage of the GDT.</p> <p><strong>[EDIT] Complete code:</strong></p> <pre><code>bits 16 org 0 ; loaded with offset 0000 (phys addr: 0x7e00) jmp Start Start: xor ax, ax mov ax, cs mov ds, ax ; update data segment cli ; clear interrupts lgdt [gdtr] ; load GDT from GDTR (see gdt_32.inc) call OpenA20Gate ; open the A20 gate call EnablePMode ; jumps to ProtectedMode ;****************** ;* Opens A20 Gate * ;****************** OpenA20Gate: in al, 0x93 ; switch A20 gate via fast A20 port 92 or al, 2 ; set A20 Gate bit 1 and al, ~1 ; clear INIT_NOW bit out 0x92, al ret ;************************** ;* Enables Protected Mode * ;************************** EnablePMode: mov eax, cr0 or eax, 1 mov cr0, eax jmp ProtectedMode ; this works (jumps to label and halts) ;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; =&gt; does not work ;jmp 08h:ProtectedMode , =&gt; does not work ;*************** ;* data fields * ;* &amp;includes * ;*************** %include "gdt_32.inc" ;****************** ;* Protected Mode * ;****************** bits 32 ProtectedMode: ;here I want to jump to physical addr 0x8000 (elf64 asm program) .halt: hlt jmp .halt </code></pre>
 

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