title: I failed in switching the cpu from real-mode to protected-mode
body: <p>I do this according a book by Nick Blundell. I write a MBR program, which runs in real-mode firstly, and some instructions in the program will switch the cpu to protected-mode.
  First I set the GDT like this:</p>
  
  <pre><code>gdt_start:
  
  gdt_null:
      dd 0x0
      dd 0x0
  
  gdt_code:
      dw 0xffff
      dw 0x0
      db 10011010b
      db 11001111b
      db 0x0
  
  gdt_data:
      dw 0xffff
      dw 0x0
      db 0x0
      db 10010010b
      db 11001111b
      db 0x0
  
  gdt_end:
  
  gdt_descriptor :
      dw gdt_end - gdt_start - 1
      dd gdt_start
  CODE_SEG equ gdt_code - gdt_start
  DATA_SEG equ gdt_data - gdt_start
  </code></pre>
  
  <p>Then the cpu runs the following instructions:</p>
  
  <pre><code>   cli
  
      lgdt [gdt_descriptor]
      mov eax,cr0
      or eax,0x1
      mov cr0,eax ;this will set the cpu to protected-mode        
  
  ;jmp $  ;I use this instrction to find where is wrong
      jmp CODE_SEG:init_pm
  
  jmp $
  [bits 32]
  init_pm:
  jmp $
      mov ax,10
  jmp $
      mov ds,eax
      mov ss,eax
  jmp $
      mov es,ax
      mov fs,ax
      mov gs,ax
      mov ebp,0x90000
      mov esp,ebp
      call BEGIN_PM
  </code></pre>
  
  <p>The instruction <code>jmp CODE_SEG:init_pm</code> will cause the cpu to crash and restart. If I change this to <code>jmp init_pm</code>, the following instruction <code>mov ax,10</code> will cause the cpu to crash and restart. And the book said the switching operation needs a long jump. </p>
  
  <p>Could you please help me do the switching operation?</p>