Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .386P
- CGROUP GROUP _TEXT, _TEXT32, _DATA, STACK
- _TEXT SEGMENT USE16 BYTE PUBLIC 'CODE'
- _TEXT ENDS
- _TEXT32 SEGMENT USE32 BYTE PUBLIC 'CODE'
- _TEXT32 ENDS
- _DATA SEGMENT USE16 WORD PUBLIC 'DATA'
- _DATA ENDS
- STACK SEGMENT USE16 PARA STACK 'STACK'
- STACK ENDS
- _DATA SEGMENT
- gdt label byte
- dq 0
- c_limit_lo dw 0ffffh
- c_base_lo dw 0
- c_base_mid db 0
- c_priv db 10011110b ;present set, highest priv, type set, conforming, read
- c_limit_hi db 11001111b ;granularity set, operand size 32
- c_base_hi db 0
- d_limit_lo dw 0ffffh
- d_base_lo dw 0
- d_base_mid db 0
- d_priv db 10010010b ;present set, highest priv, type clr, expand dn, write
- d_limit_hi db 11001111b ;granularity set, big set
- d_base_hi db 0
- ; Data selector so we can access memory in a flat memory model
- dz_limit_lo dw 0ffffh
- dz_base_lo dw 0
- dz_base_mid db 0
- dz_priv db 10010010b ;present set, highest priv, type clr, expand dn, write
- dz_limit_hi db 11001111b ;granularity set, big set
- dz_base_hi db 0
- gdt_end label byte
- gdtr label fword
- gdt_limit dw gdt_end-gdt-1
- gdt_addr dd ?
- vidmem_ptr dd 0b8000h
- in_pmode_str db "Processor already in protected mode - exiting", 0ah, 0dh, "$"
- banner_str db "The quick brown fox jumps over the lazy dog", 0
- _DATA ENDS
- _TEXT SEGMENT
- assume cs:CGROUP, ds:CGROUP
- start:
- mov ax, cs
- mov ds, ax
- mov ss, ax
- mov sp, offset CGROUP:stack_top
- ;Set the stack pointer relative to beginning of group
- ;calc phys address of current code segment and
- ;insert it into code and data descriptors
- call check_pmode ; Check if we are already in protected mode
- ; This may be the case if we are in a VM8086 task.
- ; EMM386 and other expanded memory manager often
- ; run DOS in a VM8086 task. DOS extenders will have
- ; the same effect
- jz not_prot_mode ; If not in protected mode proceed to switch
- mov dx, offset CGROUP:in_pmode_str
- ; otherwise print an error and exit back to DOS
- mov ah, 9h
- int 21h ; Print Error
- mov ax, 4c00h ; DOS Exit program
- int 21h
- not_prot_mode:
- xor eax, eax
- mov ax, cs
- shl eax, 4 ;multiply cs by 16 to get phys address of seg
- mov edx, eax
- mov c_base_lo, ax
- mov d_base_lo, ax ;low word
- shr eax, 16
- mov c_base_mid, al
- mov d_base_mid, al ;middle byte
- mov c_base_hi, ah
- mov d_base_hi, ah ;high byte
- add edx, offset CGROUP:gdt ;add offset of gdt
- mov gdt_addr, edx ;gdt address set
- ;attempt to enter protected mode
- cli ;disable interrupts
- in al, 70h
- or al, 80h
- out 70h, al ;turn off nonmasked interrupts
- in al, 92h
- or al, 2
- out 92h, al ;enable A20 line
- lgdt [gdtr]
- mov eax, cr0
- or eax, 1
- mov cr0, eax ;enter protected mode
- db 66h ;specify 32-bit operand
- db 0eah ;manually encoded "jmp 8h:enter_32"
- dw near ptr CGROUP:enter_32
- dw 0
- dw 8 ; In protected mode after executed
- ; 16-bit functions that run in real mode
- ; Check if protected mode is enabled, effectively checking if we are
- ; in in a VM8086 task. Set ZF to 1 if in protected mode
- check_pmode PROC
- smsw ax
- test ax, 1
- ret
- check_pmode ENDP
- _TEXT ENDS
- _TEXT32 SEGMENT
- enter_32:
- ; Set FS to a flat memory selector (18h) to more easily
- ; reference data from the start of memory
- mov eax, 18h
- mov fs, eax
- mov eax, 10h ; Set SS=ES=DS= selector 10h
- mov ds, eax
- mov es, eax
- mov ss, eax
- movzx esp, sp ; Zero extend SP to 32 bits (zero upper 16-bits of ESP)
- ; Print banner strong in upper left of screen with white on magenta colors
- mov esi, offset CGROUP:banner_str
- mov ah, 5fh ; Attribute WHite on Magenta.
- call print_string_pm
- back:jmp back ; but always triple faults on mov
- ; Function: print_string_pm
- ; Display a string to the console on display page 0 in protected mode.
- ; Very basic. Doesn't update hardware cursor, doesn't handle scrolling,
- ; LF, CR, TAB. FS must be a flat memory selector.
- ;
- ; Inputs: ESI = Offset of address to print
- ; AH = Attribute of string to print
- ; Clobbers: EAX
- ; Returns: None
- print_string_pm PROC
- push edi
- push esi
- mov edi, [vidmem_ptr] ; Start from video address stored at vidmem_ptr
- jmp .getchar
- .outchar:
- mov fs:[edi], ax
- add edi, 2 ; Output character to video display
- .getchar:
- lodsb ; Load next character from string
- test al, al ; Is character NUL?
- jne .outchar ; If not, go back and output character
- mov [vidmem_ptr], edi ; Update global video pointer
- pop esi
- pop edi
- ret
- print_string_pm ENDP
- _TEXT32 ENDS
- STACK SEGMENT
- the_stack db 64 dup (?) ;64 byte stack
- stack_top label byte
- STACK ENDS
- end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement