Last active
April 19, 2019 02:08
-
-
Save lighth7015/a8239242a1440a637f91ba95fcceb85d to your computer and use it in GitHub Desktop.
Enter/Leave Protected Mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
org 100h | |
bits 16 | |
section .text | |
global __start | |
jmp __start | |
Unsupported db 'This application requires at least an 80386 processor.', 0x0d, 0x0a, '$' ; $-terminated message | |
AlreadyInit db 'Already in Protected Mode!', 0x0d, 0x0a, '$' ; $-terminated message | |
A20LineFail db 'A20 Line is Disabled or Not Present.', 0x0d, 0x0a, '$' ; $-terminated message | |
SuccessMesg db 'Successfully returned to real mode.', 0x0d, 0x0a, '$' ; $-terminated message | |
IsSupportedCPU: pushf ; save flags | |
cli ; make sure no ISR will interfere now | |
; | |
pushf ; 1. make sure have at least 386 | |
pop ax ; AX=flags | |
xor ah, 0x40 ; toggle NT | |
push ax ; stack: modified_flags,original_flags | |
popf ; | |
pushf ; stack: modified_flags_from_cpu,original_flags | |
pop dx ; DX=flags passed via CPU | |
mov al, dh ; | |
xor al, ah ; | |
jnz UnsupportedCPU ; improper CPU | |
; | |
smsw ax ; 2. make sure are in Real Mode | |
and al, 1 ; | |
jnz UnsupportedCPU ; if already in PM (maybe V8086) | |
; | |
push ds ; 3. make sure A20 is enabled | |
push es ; | |
push bx ; | |
xor bx, bx ; | |
mov ds, bx ; | |
mov ax, -1 ; | |
mov es, ax ; | |
xor [bx], ah ; change byte[000000h] | |
mov al, [es:bx + 0x10] ; get byte[100000h] | |
xor [bx], ah ; change byte[000000h] | |
xor al, [es:bx + 0x10] ; compare byte[100000h] with its previous value | |
; 0 if unchanged, -1 means [000000h]==[100000h] | |
pop bx ; | |
pop es ; | |
pop ds ; | |
; | |
UnsupportedCPU: popf ; restore flags | |
test al, al ; test error code | |
ret | |
ExitWithError: lea dx, [A20LineFail] | |
jc WriteAndExit | |
lea dx, [Unsupported] | |
js WriteAndExit | |
lea dx, [AlreadyInit] | |
WriteAndExit: mov ah, 9 ; | |
int 21h ; | |
mov ax, 4cffh ; exit, status=-1 | |
int 21h ; | |
__start: call IsSupportedCPU | |
add al, al | |
jnz ExitWithError | |
mov dx, SuccessMesg | |
call WriteAndExit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment