Advertisement
MichaelPetch

SO 78385653

Apr 25th, 2024 (edited)
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.86 KB | None | 0 0
  1. bits 16
  2. ORG 0x7c00
  3.  
  4. start:
  5. xor ax, ax
  6. mov ds, ax
  7.  
  8. ; Enter 32-bit protected mode
  9. cli
  10. lgdt [gdt.gdtr]
  11. mov eax, cr0
  12. or eax, 1
  13. mov cr0, eax
  14. jmp CODE32_PL0_SEL:.prot32mode
  15.  
  16. bits 32
  17. .prot32mode:
  18. mov eax, DATA32_PL0_SEL
  19. mov ds, eax
  20. mov es, eax
  21. mov fs, eax
  22. mov gs, eax
  23. mov ss, eax
  24. mov esp, 0x90000
  25. lidt [idt.idtr]
  26.  
  27. ; 32-bit Protected mode code here!!!
  28. mov bx, 0xd20
  29.  
  30. ; Start switching back to real mode
  31. ; Must use a 16-bit code segment and enter 16-bit
  32. ; Protected mode FIRST.
  33. jmp CODE16_PL0_SEL:.prot16mode
  34.  
  35. bits 16
  36. .prot16mode:
  37. ; Load the segment registers with 16-bit descriptors
  38. mov ax, DATA16_PL0_SEL
  39. mov ds, ax
  40. mov es, ax
  41. mov fs, ax
  42. mov gs, ax
  43. mov ss, ax
  44.  
  45. ; Leave 16-bit protected mode back to real mode
  46. lidt [idtr_real]
  47. mov eax, cr0
  48. and al, ~1
  49. mov cr0, eax
  50. jmp 0:.realmode
  51.  
  52. .realmode:
  53. ; Set up a stack and set the real mode segment registers
  54. xor ax, ax
  55. mov ds, ax
  56. mov es, ax
  57. mov ss, ax
  58. mov sp, 0x7c00
  59.  
  60. sti ; Enable interrupts(not necessary for this code)
  61. cld ; Set DF (Direction Flag) forward.
  62.  
  63. mov bx, 0xd00
  64. mov si, realmodestr
  65. call print_string_16
  66.  
  67. hltloop:
  68. hlt
  69. jmp hltloop
  70.  
  71. realmodestr: db "Back in real mode!", 0
  72.  
  73. ; Function: print_string_16
  74. ; Display a string to the console on display page 0
  75. ;
  76. ; Inputs: SI = Offset of address to print
  77. ; Clobbers: AX, BX, SI
  78.  
  79. print_string_16:
  80. mov ah, 0x0e ; BIOS tty Print
  81. xor bx, bx ; Set display page to 0 (BL)
  82. jmp .getch
  83. .repeat:
  84. int 0x10 ; print character
  85. .getch:
  86. lodsb ; Get character from string
  87. test al,al ; Have we reached end of string?
  88. jnz .repeat ; if not process next character
  89. .end:
  90. ret
  91.  
  92. ; Macro to build a GDT descriptor entry
  93. %define MAKE_GDT_DESC(base, limit, access, flags) \
  94. dq (((base & 0x00FFFFFF) << 16) | \
  95. ((base & 0xFF000000) << 32) | \
  96. (limit & 0x0000FFFF) | \
  97. ((limit & 0x000F0000) << 32) | \
  98. ((access & 0xFF) << 40) | \
  99. ((flags & 0x0F) << 52))
  100.  
  101. ; GDT structure
  102. align 4
  103. gdt:
  104. CODE32_PL0_SEL EQU .code32_pl0 - .start
  105. DATA32_PL0_SEL EQU .data32_pl0 - .start
  106. CODE16_PL0_SEL EQU .code16_pl0 - .start
  107. DATA16_PL0_SEL EQU .data16_pl0 - .start
  108.  
  109. .start: MAKE_GDT_DESC(0, 0, 0, 0)
  110. ; Null descriptor
  111. .code32_pl0: MAKE_GDT_DESC(0, 0x00ffffff, 10011010b, 1100b)
  112. ; 32-bit code, privilege level 0, gran=page, limit 0xffffffff
  113. .data32_pl0: MAKE_GDT_DESC(0, 0x00ffffff, 10010010b, 1100b)
  114. ; 32-bit data, privilege level 0, gran=page, limit 0xffffffff
  115. .code16_pl0: MAKE_GDT_DESC(0, 0x0000ffff, 10011010b, 0000b)
  116. ; 16-bit code, privilege level 0, gran=byte, limit 0x0000ffff
  117. .data16_pl0: MAKE_GDT_DESC(0, 0x0000ffff, 10010010b, 0000b)
  118. ; 16-bit data, privilege level 0, gran=byte, limit 0x0000ffff
  119. .end:
  120.  
  121. ; Protected mode GDT record
  122. .gdtr:
  123. dw .end - .start - 1 ; limit (Size of GDT - 1)
  124. dd .start ; base of GDT
  125.  
  126. ; Protected mode IDT
  127. idt:
  128. .start:
  129. ; This should be filled in with proper interrupt handlers
  130. .end:
  131.  
  132. ; Protected mode IDT record
  133. .idtr:
  134. dw .end - .start - 1 ; limit (Size of GDT - 1)
  135. dd .start ; base of GDT
  136.  
  137. ; IDTR for REAL Mode
  138. idtr_real:
  139. dw 0x3ff ; Real mode IVT is 0x3ff+1 bytes in size
  140. dd 0 ; Real mode IVT starts at bottom of memory
  141.  
  142. ; Pad boot sector to 510 bytes and add 2 byte boot signature for 512 total bytes
  143. TIMES 510-($-$$) db 0
  144. dw 0xaa55
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement