
1. ; Paging.asm
2. ; Copyright (C) 1997, Jean L. Gareau
3. ;
4. ; This program demonstrates how to enable paging in protected mode.
5. ; A flat memory model and a simplified segment
definition are used.
6. ;
7. ; This program has been assembled with MASM 6.11:
8. ; C:\>ML ProtMode32.asm
9. ;
10. ; When linked, it must have a base address of BASE (F0000000h in this example),
11. ; which is where this code is to be mapped in its address space.
12.
13. BASE EQU 0F0000000h ; Base address (virtual)
14.
15. .386P ; Use 386+ privileged instructions
16.
17. ;ıııııııııııııııııııııııııııııııııııııı-;
18. ; Macros (to use 32-bit instructions while in real mode) ;
19.
;ıııııııııııııııııııııııııııııııııııııı-;
20.
21. LGDT32 MACRO Addr ; 32-bit LGDT Macro in 16-bit
22. DB 66h ; 32-bit operand override
23. DB 8Dh ; lea (e)bx,Addr
24. DB 1Eh
25. DD Addr
26. DB 0Fh ; lgdt fword ptr [bx]
27. DB 01h
28. DB 17h
29. ENDM
30.
31. FJMP32 MACRO Selector,Offset ; 32-bit Far Jump Macro in 16-bit
32. DB 66h ; 32-bit operand override
33. DB 0EAh ; far jump
34. DD Offset ; 32-bit offset
35. DW Selector ; 16-bit selector
36. ENDM
37.
38. PUBLIC _EntryPoint ; The linker needs it.
39.
40. _TEXT SEGMENT PARA USE32 PUBLIC ıCODE'
41. ASSUME CS:_TEXT
42.
43. ;ıııııııııııııııııııııııııııııııııııııı-;
44. ; Page Directory and Page Table. ;
45. ;ıııııııııııııııııııııııııııııııııııııı-;
46.
47. ORG 3000h ; => Depends on code location.
<
=
48.
49. PD:
50. dd 1024 DUP (0) ; Page Directory: all entries at 0.
51. PT:
52. dd 1024 DUP (0) ; Page Table : all entries at 0.
53.
54. ;ıııııııııııııııııııııııııııııııııııııı-;
55. ; Entry Point. The CPU is executing in 16-bit real mode.
;
56. ;ıııııııııııııııııııııııııııııııııııııı-;
57.
58. ORG 5000h ; => Depends on code location.
<
=
59.
60. _EntryPoint:
61.
62. LGDT32 GdtDesc - BASE ; Load GDT descriptor
63.
64. mov eax,cr0 ; Get control register 0
65. or ax,1 ; Set PE bit (bit #0) in (e)ax
66. mov cr0,eax ; Activate protected mode!
67. jmp $+2 ; Flush the instruction queue.
68.
69. ; The CPU is now executing in 16-bit protected mode. Make a far jump in order to
70. ; load CS with a selector to a 32-bit executable code
descriptor.
71.
72. FJMP32 08h,Start32 - BASE ; Jump to Start32 (below)
73.
74. ; This point is never reached. Data follow.
75.
76. GdtDesc: ; GDT descriptor
77. dw GDT_SIZE - 1 ; GDT limit
78. dd Gdt ; GDT base address (below)
79.
80. ;ıııııııııııııııııııııııııııııııııııııı-;
81. ; The CPU is now executing in 32-bit protected mode. ;
82. ;ıııııııııııııııııııııııııııııııııııııı-;
83.
84. Start32:
85.
86. ; Initialize all segment registers to 10h (entry #2 in the GDT)
87.
88. mov ax,10h ; entry #2
in GDT
89. mov ds,ax ; ds = 10h
90. mov es,ax ; es = 10h
91. mov fs,ax ; fs = 10h
92. mov gs,ax ; gs = 10h
93. mov ss,ax ; ss = 10h
94.
95. ; Set the top of stack to allow stack operations.
96.
97. mov esp,8000h ; arbitrary top of stack
98.
99. ; Store the PT address into PDE 0 and 960.
100.
101. mov eax,offset Pd - BASE ; eax = &PD
102. mov ebx,offset Pt - BASE + 3 ; ebx = &PT | 3
103. mov [eax],ebx ; PD[0] = &PT
104.
105. mov eax,offset Pd - BASE + 960 * 4 ; eax = &PDE[960]
106.
mov [eax],ebx ; PD[960] = &PT
107.
108. ; Initialize the PT to cover the first 4 MB of physical memory.
109.
110. mov edi,offset Pt - BASE ; edi = &PT
111. mov eax,3 ; Address 0, bit p & r/w set
112. mov ecx,1024 ; 1024 entries
113. InitPt:
114. stosd ; Write one entry
115. add eax,1000h ; Next page address
116. loop InitPt ; Loop
117.
118. ; Turn on paging by:
119. ; 1) setting the PD address into CR3 and
120.
121. mov eax,offset Pd - BASE ; eax = &PD
122. mov cr3,eax ; cr3 = &PD
123.
124. ; 2) setting CR0's PG bit.
125.
126. mov eax,cr0
127. or eax,80000000h ; Set PG bit
128. mov cr0,eax ; Paging is on!
129. jmp $+2 ; Flush the instruction queue.
130.
131. ; Let's now jump to F000xxxx.
132.
133. push offset PagingMode ; Keep full address (F000xxxxh)
134. ret ; Jump at Paging Mode (below)
135.
136. PagingMode:
137.
138. ;ıııııııııııııııııııııııııııııııııııııı-;
139. ; -> Paging is now enabled, executing code at F000xxxxh
<
ı ;
140.
;ıııııııııııııııııııııııııııııııııııııı-;
141.
142. ; Other initialization instructions come here.
143. ; ...
144.
145. ; This point is never reached. Data follow.
146.
147. ;ıııııııııııııııııııııııııııııııııııııı-;
148. ; GDT ;
149. ;ıııııııııııııııııııııııııııııııııııııı-;
150.
151. ; Global Descriptor Table (GDT) (faster accessed if aligned on 4).
152.
153. ALIGN 4
154.
155. Gdt:
156.
157. ; GDT[0]: Null entry, never used.
158.
159. dd 0
160. dd 0
161.
162. ; GDT[1]: Executable, read-only code, base address of 0,
limit of FFFFFh,
163. ; granularity bit (G) set (making the limit 4GB)
164.
165. dw 0FFFFh ; Limit[15..0]
166. dw 0000h ; Base[15..0]
167. db 00h ; Base[23..16]
168. db 10011010b ; P(1) DPL(00) S(1) 1 C(0) R(1) A(0)
169. db 11001111b ; G(1) D(1) 0 0 Limit[19..16]
170. db 00h ; Base[31..24]
171.
172. ; GDT[2]: Writable data segment, covering the save address space than GDT[1].
173.
174. dw 0FFFFh ; Limit[15..0]
175. dw 0000h ; Base[15..0]
176. db 00h ; Base[23..16]
177. db
10010010b ; P(1) DPL(00) S(1) 0 E(0) W(1) A(0)
178. db 11001111b ; G(1) B(1) 0 0 Limit[19..16]
179. db 00h ; Base[31..24]
180.
181. GDT_SIZE EQU $ - offset Gdt ; Size, in bytes
182.
183. _TEXT ENDS
184. END
|