Listing 1 Sixteen-bit and 32-bit code segments. Opcodes are shown on the left. 1. _TEXT SEGMENT PARA USE16 PUBLIC 'CODE' 2. 33 C0 xor ax,ax 3. 66 33 C0 xor eax,eax 4. _TEXT ENDS 5. 6. _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' 7. 33 C0 xor eax,eax 8. 66 33 C0 xor ax,ax 9. _TEXT ENDS Listing 2 Although many instructions are identical in 16-bit and 32-bit, addressing modes and addresses always generate different opcodes, making the code incompatible. 1. _TEXT SEGMENT PARA USE16 PUBLIC 'CODE' 2. 8D 06 0024 lea ax,MyVar 3. _TEXT ENDS 4. 5. _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' 6. 66 8D 05 00000024 lea ax,MyVar 7. 8D 05 00000024 lea eax,MyVar 8. _TEXT ENDS Listing 3 Switching from 16-bit real mode to 32-bit protected mode. 1. ; ProtMode.asm 2. ; Copyright (C) 1998, Jean L. Gareau 3. ; 4. ; This program demonstrates how to switch from 16-bit real mode into 5. ; 32-bit protected mode. Some real mode instructions are implemented with macros 6. ; in order for them to use 32-bit operands. 7. ; 8. ; This program has been assembled with MASM 6.11: 9. ; C:\>ML ProtMode32.asm 10. 11. .386P ; Use 386+ privileged instructions 12. 13. ;-----------------------------------------------------------------------------; 14. ; Macros (to use 32-bit instructions while in real mode) ; 15. ;-----------------------------------------------------------------------------; 16. 17. LGDT32 MACRO Addr ; 32-bit LGDT Macro in 16-bit 18. DB 66h ; 32-bit operand override 19. DB 8Dh ; lea (e)bx,Addr 20. DB 1Eh 21. DD Addr 22. DB 0Fh ; lgdt fword ptr [bx] 23. DB 01h 24. DB 17h 25. ENDM 26. 27. FJMP32 MACRO Selector,Offset ; 32-bit Far Jump Macro in 16-bit 28. DB 66h ; 32-bit operand override 29. DB 0EAh ; far jump 30. DD Offset ; 32-bit offset 31. DW Selector ; 16-bit selector 32. ENDM 33. 34. PUBLIC _EntryPoint ; The linker needs it. 35. 36. _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' 37. ASSUME CS:_TEXT 38. 39. ORG 5000h ; => Depends on code location. 40. 41. ;-----------------------------------------------------------------------------; 42. ; Entry Point. The CPU is executing in 16-bit real mode. ; 43. ;-----------------------------------------------------------------------------; 44. 45. _EntryPoint: 46. 47. LGDT32 fword ptr GdtDesc ; Load GDT descriptor 48. 49. mov eax,cr0 ; Get control register 0 50.. or ax,1 ; Set PE bit (bit #0) in (e)ax 51. mov cr0,eax ; Activate protected mode! 52. jmp $+2 ; To flush the instruction queue. 53. 54. ; The CPU is now executing in 16-bit protected mode. Make a far jump in order to 55. ; load CS with a selector to a 32-bit executable code descriptor. 56. 57. FJMP32 08h,Start32 ; Jump to Start32 (below) 58. 59. ; This point is never reached. Data follow. 60. 61. GdtDesc: ; GDT descriptor 62. dw GDT_SIZE - 1 ; GDT limit 63. dd Gdt ; GDT base address (below) 64. 65. Start32: 66. 67. ;-----------------------------------------------------------------------------; 68. ; The CPU is now executing in 32-bit protected mode. ; 69. ;-----------------------------------------------------------------------------; 70. 71. ; Initialize all segment registers to 10h (entry #2 in the GDT) 72. 73. mov ax,10h ; entry #2 in GDT 74. mov ds,ax ; ds = 10h 75. mov es,ax ; es = 10h 76. mov fs,ax ; fs = 10h 77. mov gs,ax ; gs = 10h 78. mov ss,ax ; ss = 10h 79. 80. ; Set the top of stack to allow stack operations. 81. 82. mov esp,8000h ; arbitrary top of stack 8 84. ; Other initialization instructions come here. 85. ; ... 86. 87. ; This point is never reached. Data follow. 88. 89. ;-----------------------------------------------------------------------------; 90. ; GDT ; 91. ;-----------------------------------------------------------------------------; 92. 93. ; Global Descriptor Table (GDT) (faster accessed if aligned on 4). 94. 95. ALIGN 4 96. 97. Gdt: 98. 99. ; GDT[0]: Null entry, never used. 100. 101. dd 0 102. dd 0 103. 104. ; GDT[1]: Executable, read-only code, base address of 0, limit of FFFFFh, 105. ; granularity bit (G) set (making the limit 4GB) 106. 107. dw 0FFFFh ; Limit[15..0] 108. dw 0000h ; Base[15..0] 109. db 00h ; Base[23..16] 110. db 10011010b ; P(1) DPL(00) S(1) 1 C(0) R(1) A(0) 111. db 11001111b ; G(1) D(1) 0 0 Limit[19..16] 112. db 00h ; Base[31..24] 113. 114. ; GDT[2]: Writable data segment, covering the save address space than GDT[1]. 115. 116. dw 0FFFFh ; Limit[15..0] 117. dw 0000h ; Base[15..0] 118. db 00h ; Base[23..16] 119. db 10010010b ; P(1) DPL(00) S(1) 0 E(0) W(1) A(0) 120. db 11001111b ; G(1) B(1) 0 0 Limit[19..16] 121. db 00h ; Base[31..24] 122. 123. GDT_SIZE EQU $ - offset Gdt ; Size, in bytes 124. 125. _TEXT ENDS 126. END