;Определения для защищенного режима работы программы
;Структура дескриптора
desc_struc STRUC
limit dw 0
base_l dw 0
base_h db 0
access db 0
rsrv dw 0
desc_struc ENDS
ACC_PRESENT equ 10000000b
ACC_CSEG equ 00011000b
ACC_DSEG equ 00010000b
ACC_EXPDOWN equ 00000100b
ACC_CONFORM equ 00000100b
ACC_DATAWR equ 00000010b
DATA_ACC=ACC_PRESENT or ACC_DSEG or ACC_DATAWR
; 10010010b
CODE_ACC=ACC_PRESENT or ACC_CSEG or ACC_CONFORM
; 10011100b
STACK_ACC=ACC_PRESENT or ACC_DSEG or ACC_DATAWR or ACC_
EXPDOWN; 10010110b
;Размеры сегментов (реальные размеры на единицу больше)
CSEG_SIZE=65535
DSEG_SIZE=65535
STACK_SIZE=65535
;Смещения используемых дескрипторов
CS_DESCR=(gdt_cs–gdt_0)
DS_DESCR=(gdt_ds–gdt_0)
SS_DESCR=(gdt_ss–gdt_0)
;Константы значений портов
CMOS_PORT equ 70h
STATUS_PORT equ 64h
SHUT_DOWN equ 0FEh
A20_PORT equ 0D1h
A20_ON equ 0DFh
A20_OFF equ 0DDh
INT_MASK_PORT equ 21h
KBD_PORT_A equ 60h
start:
;Инициализируем необходимые данные для перехода
;в защищенный режим
call init_protected_mode
;Переходим в защищенный режим
call set_protected_mode
;Теперь компьютер работает в защищенном режиме!
;Так как таблица прерываний реального режима не может быть
;использована в защищенном, прерывания запрещены!
;Именно тут можно вставить инструкции, нужные вирусу
;Возвращаемся в реальный режим
call set_real_mode
;Печатаем сообщение ”Light General”
mov ah,09h
lea dx,qw
int 21h
;Выходим в DOS
mov ax,4C00h
int 21h
;Макрокоманда для установки адреса для дескриптора
;в глобальной таблице дескрипторов GDT.
;На входе регистры DL:AX должны содержать
;абсолютный адрес сегмента
setgdtentry MACRO
mov [desc_struc.base_l][bx],ax
mov [desc_struc.base_h][bx],dl
ENDM
;Процедура инициализации необходимых данных
;для перехода в защищенный режим
init_protected_mode PROC
;Вычисляем абсолютный адрес для сегмента данных
;в соответствии со значением регистра DS
mov ax,ds
mov dl,ah
shr dl,4
shl ax,4
;Устанавливаем адрес сегмента данных
;в глобальной таблице дескрипторов
mov bx,offset gdt_ds
setgdtentry
;Вычисляем абсолютный адрес для сегмента GDT: прибавляем
;к уже вычисленному абсолютному адресу сегмента данных
;смещение в нем таблицы дескрипторов
add ax,offset gdtr
adc dl,0
;Устанавливаем адрес сегмента GDT
;в глобальной таблице дескрипторов
mov bx,offset gdt_gdt
setgdtentry
;Вычисляем абсолютный адрес для сегмента кода
;в соответствии со значением регистра CS
mov ax,cs
mov dl,ah
shr dl,4
shl ax,4
;Устанавливаем адрес сегмента кода
;в глобальной таблице дескрипторов
mov bx,offset gdt_cs
setgdtentry
;Вычисляем абсолютный адрес для сегмента стека
;в соответствии со значением регистра SS
mov ax,ss
mov dl,ah