Показать сообщение отдельно
Старый 15.06.2011, 16:20   #6
saovu
Gold Member
 
Регистрация: 07.09.2005
Сообщений: 1,326
По умолчанию

Продолжаем безумство цитирования исходников ...

Фрагмент программы, переводящей процессор из реального режима в защищенный

Скрытый текст



IDEAL
P386
LOCALS

BackKey EQU 10
EnterKey EQU 11
NoKey EQU 12
Common EQU offset Code_D
Left EQU 5
Right EQU 44

STRUC Descr ; структура для описания дескриптора сегмента ;;;;;;;;;;;;;;;;;;;
Lim dw 0; граница ( биты 0..15 )
Base_L dw 0; база, биты 0..15
Base_M db 0; база, биты 16..23
Attr_1 db 0; байт атрибутов 1
Attr_2 db 0; граница ( биты 16..19 ) и атрибуты 2
Base_H db 0; база, биты 24..31
ENDS

STRUC Gate ; структура для описания дескриптора шлюза ;;;;;;;;;;;;;;;;;;;;;;;
Offs_L dw 0; смещение ( биты 0..15 )
Sel dw 0; селектор задачи
Count db 0; слово пересчета ( биты 0..4 )
Attr db 0; байт атрибутов
Offs_H dw 0; смещение ( биты 16..31 )
ENDS

MACRO Mov_Seg seg, addr ; загрузка сегментного регистра
mov AX, addr ; через регистр AX
mov seg, AX ; в регистр seg
ENDM

MACRO Make_Linear seg ; создание линейного адреса
xor EAX, EAX ; старшее слово := 0
mov AX, seg ; в младшее - seg
shl EAX, 4 ; сдвиг - и все Ok
ENDM

MACRO Put_To_GDT where, seg ; зарегистрировать в GDT
make_linear seg ; получение линейного адреса
mov [Where.Base_L], AX ; биты 0..15
rol EAX, 16 ; меняем слова EAX
mov [Where.Base_M], AL ; биты 16..19 (дальше нули)
ENDM

MACRO Load_GDTR ; загрузка регистра GDTR
make_linear GDT ; получение линейного адреса
mov [DWORD GDT_PTR + 2], EAX ; база GDT, биты 0..31
mov [WORD GDT_PTR + 0], GDT_Size-1 ; граница GDT
lgdt [GDT_PTR] ; загрузка таблицы
ENDM

MACRO Load_IDTR ; загрузка регистра IDTR
make_linear IDT ; получение линейного адреса
mov [DWORD IDT_PTR + 2], EAX ; база IDT, биты 0..31
mov [WORD IDT_PTR + 0], IDT_Size-1 ; граница IDT
lidt [IDT_PTR] ; загрузка таблицы
ENDM

MACRO Jmp_Next seg ; очистка очереди команд
db 0EAh ; jmp (seg)next)
dw $+4 ; адрес следующей команды
dw seg ; сегмент или селектор
ENDM

MACRO Load_Selectors_Protected
mov_seg SS, <offset Stk0_D> ; селектор сегмента стека
mov_seg DS, <offset Dat0_D> ; селектор сегмента данных
mov_seg ES, <offset Scr_D> ; селектор сегмента Scr
mov_seg FS, <offset Dat0_D> ; селектор сегмента данных
mov_seg GS, <offset GDT_D> ; селектор сегмента GDT
ENDM

MACRO Load_Selectors_Real
mov_seg SS, Stk0 ; стек
mov_seg DS, Dat0 ; данные
mov_seg ES, Scr ; Scr
mov_seg FS, Dat0 ; данные
mov_seg GS, GDT ; GDT
ENDM

MACRO Sti_All
sti ; разрешить маскируемые
mov AL, 0h ; разрешить немаскируемое
out 70h, AL ;
ENDM

MACRO Cli_All
cli ; запретить маскируемые
mov AL, 80h ; запретить немаскируемое
out 70h, AL ;
ENDM

MACRO Set_Limits_Real
mov [Code_D.Lim], 0FFFFh ; CS
mov [Stk0_D.Lim], 0FFFFh ; SS
mov [Dat0_D.Lim], 0FFFFh ; DS и FS
mov [Scr_D.Lim ], 0FFFFh ; ES
mov [GDT_D.Lim ], 0FFFFh ; GS
ENDM

; объявляя TSSы вызываемых задач, инициализируем их

SEGMENT TSS0 ; сегмент TSS главной задачи
tss{ ESP0 = Stk0_Size, \
SS0 = offset Stk0_D, \
ESP1 = Stk0_Size, \
SS1 = offset Stk0_D, \
ESP2 = Stk0_Size, \
SS2 = offset Stk0_D }
ENDS ;

SEGMENT TSS1 ; сегмент TSS задачи 1
tss{ ESP0 = Stk1_Size, \
SS0 = offset Stk1_D, \
ESP1 = Stk1_Size, \
SS1 = offset Stk1_D, \
ESP2 = Stk1_Size, \
SS2 = offset Stk1_D, \
EIP = offset Game, \
ESP = Stk1_Size, \
SS = offset Stk1_D, \
CS = offset Code_D, \
DS = offset Dat0_D, \
ES = offset Scr_D, \
FS = offset Dat1_D, \
GS = offset Null_D }
ENDS ;

SEGMENT TSS2 ; сегмент TSS задачи 2
tss{ ESP0 = Stk2_Size, \
SS0 = offset Stk2_D, \
ESP1 = Stk2_Size, \
SS1 = offset Stk2_D, \
ESP2 = Stk2_Size, \
SS2 = offset Stk2_D, \
ESP = Stk2_Size, \
EIP = offset Game, \
SS = offset Stk2_D, \
CS = offset Code_D, \
DS = offset Dat0_D, \
ES = offset Scr_D, \
FS = offset Dat2_D, \
GS = offset Null_D }
ENDS ;

SEGMENT TSSD ; сегмент TSS драйвера
tss{ ESP0 = StkD_Size, \
SS0 = offset StkD_D, \
ESP1 = StkD_Size, \
SS1 = offset StkD_D, \
ESP2 = StkD_Size, \
SS2 = offset StkD_D, \
EIP = offset Driver, \
SS = offset StkD_D, \
CS = offset Code_D, \
DS = offset Dat0_D, \
ES = offset Scr_D, \
FS = offset Dat0_D, \
GS = offset Null_D }
ENDS ;

SEGMENT GDT ; таблица глобальных дескрипторов GDT
Null_D descr <0 ,0,0,00h,0,0> ; пустой сегмент
Zero_D descr <0FFFFh ,0,0,92h,0,0> ; нулевой сегмент
Code_D descr <Code_Size-1,0,0,9Ch,0,0> ; сегмент кодa программы
Dat0_D descr <Dat0_Size-1,0,0,92h,0,0> ; сегмент даннных
Dat1_D descr <Dat1_Size-1,0,0,92h,0,0> ; сегмент даннных 1
Dat2_D descr <Dat2_Size-1,0,0,92h,0,0> ; сегмент даннных 2
Stk0_D descr <Stk0_Size-1,0,0,92h,0,0> ; сегмент стека 0
Stk1_D descr <Stk1_Size-1,0,0,92h,0,0> ; сегмент стека 1
Stk2_D descr <Stk2_Size-1,0,0,92h,0,0> ; сегмент стека 2
StkD_D descr <StkD_Size-1,0,0,92h,0,0> ; сегмент стека драйвера
Scr_D descr <Scr_Size -1,0,0,92h,0,0> ; видеобуфер
GDT_D descr <GDT_Size -1,0,0,92h,0,0> ; GDT
IDT_D descr <IDT_Size -1,0,0,92h,0,0> ; IDT
TSS0_D descr <TSS_Size -1,0,0,89h,0,0> ; TSS главной задачи
TSS1_D descr <TSS_Size -1,0,0,89h,0,0> ; TSS первой задачи
TSS2_D descr <TSS_Size -1,0,0,89h,0,0> ; TSS второй задачи
TSSD_D descr <TSS_Size -1,0,0,89h,0,0> ; TSS драйвера
ENDS ;

SEGMENT IDT ; таблица дескрипторов прерываний IDT
gate <int0 ,common,0,8Eh,0> ; 0 - деление на ноль
gate <int1 ,common,0,8Eh,0> ; 1 - отладка
gate <int2 ,common,0,8Eh,0> ; 2 - INT 2 или NMI
gate <int3 ,common,0,8Eh,0> ; 3 - точка останова
gate <int4 ,common,0,8Eh,0> ; 4 - переполнение
gate <int5 ,common,0,8Eh,0> ; 5 - контроль границ
gate <int6 ,common,0,8Eh,0> ; 6 - неправильный КОП
gate <int7 ,common,0,8Eh,0> ; 7 - отсутствие сопроцессора
gate <int8 ,common,0,8Eh,0> ; 8 - двойная ошибка
gate <int9 ,common,0,8Eh,0> ; 9 - перегрузка сегмента сопр.
gate <int10,common,0,8Eh,0> ; 10 - неправильный TSS
gate <int11,common,0,8Eh,0> ; 11 - отсутствует сегмент
gate <int12,common,0,8Eh,0> ; 12 - ошибка стека
gate <int13,common,0,8Eh,0> ; 13 - общая ошибка защиты
gate <int14,common,0,8Eh,0> ; 14 - отсутствие страницы
gate <int15,common,0,8Eh,0> ; 15 - резерв
gate <int16,common,0,8Eh,0> ; 16 - ошибка сопроцессора
gate 15 dup (<intXX,common,0,8Eh,0>) ; 17..31 - резерв
ENDS ;


ASSUME CS:Code, SS:Stk0, DSat0, ES:Scr, FSat0, GS:GDT

SEGMENT Code ;

PROC Main
load_selectors_real
; проверка типа процессора
pushf
xor AX, AX
push AX
popf
pushf
pop AX
and AX, 0F000h
cmp AX, 0F000h
je @@CPU_8086
mov AX, 0F000h
push AX
popf
pushf
pop AX
and AX, 0F000h
jz @@CPU_80286
jmp @@CPU_80386_or_better

@@CPU_8086:
mov DX, OFFSET mess_8086
jmp @@contunie_to_exit
@@CPU_80286:
mov DX, OFFSET mess_80286
@@contunie_to_exit:
mov AH, 09h
int 21h
popf
jmp @@exit

@@CPU_80386_or_better:
popf

; подготовка GDT и GDTR
put_to_gdt Zero_D, 0 ; нулевой сегмент
put_to_gdt Code_D, Code ; кодовый сегмент
put_to_gdt Stk0_D, Stk0 ; сегмент стека программы
put_to_gdt Dat0_D, Dat0 ; сегмент данных программы
put_to_gdt Dat1_D, Dat1 ; сегмент данных задачи 1
put_to_gdt Dat2_D, Dat2 ; сегмент данных задачи 2
put_to_gdt Scr_D, Scr ; сегмент видеобуфера
put_to_gdt GDT_D, GDT ; сегмент GDT
put_to_gdt IDT_D, IDT ; сегмент IDT
put_to_gdt TSS0_D, TSS0 ; TSS главной задачи
put_to_gdt TSS1_D, TSS1 ; TSS задачи 1
put_to_gdt TSS2_D, TSS2 ; TSS задачи 2
put_to_gdt TSSD_D, TSSD ; TSS драйвера
load_gdtr ; загрузка регистра GDTR

; запрещение прерываний
cli_all

; переходим в защищенный режим
mov EAX, CR0
or EAX, 1
mov CR0, EAX
jmp_next <offset Code_D>
load_selectors_protected

; загрузка TR
mov AX, offset TSS0_D
ltr AX

; подготовка IDT и IDTR
load_idtr

call Random
call ClrScr PASCAL, '░', [attr1]
call PutBar PASCAL, 00, ' ', [attr2]
call PutBar PASCAL, 24, ' ', [attr2]
call Box PASCAL, 03, 4, 37, 20, ' ', 2, \
offset Header1, [attr2], [attr3], [attr4]
call Box PASCAL, 42, 4, 76, 20, ' ', 2, \
offset Header2, [attr2], [attr3], [attr4]
call WriteStr PASCAL, 26, 0, offset Sym, [attr2]

cycle:

mov CL,7
call Random
call [dword KeyDrv] ; вызов драйвера
call [dword Task1] ; вызов задачи 1
call [dword Task2] ; вызов задачи 2
cmp [ScanWord],1 ; нажата Esc ?
jne cycle ; нет - продолжить

return_real:

; настройка границ для реального режима
set_limits_real
jmp_next <offset Code_D>
load_selectors_protected

; переключаем . . .
mov EAX, CR0
and EAX, 0FFFFFFFEh
mov CR0, EAX
jmp_next Code
load_selectors_real

; установка IDTR на 256 прерываний реального режима
; загрузкой границы и базового адреса таблицы прерываний
lidt [STD_PTR]

; разрешение прерываний
sti_all

call WriteStr PASCAL, 27, 24, offset Mes, [attr2]

@@exit:
mov AX, 4C00h
int 21h
ENDP Main

PROC ErrorMess NEAR ; прерывание [DS:SI], BL - позиция, BH - цвет
xor DI, DI
mov AX, 80*2
mul BL
add DI, AX
cld
mov AH, BH
lodsb
@@1:
stosw
lodsb
cmp AL,'$'
jne @@1
ret
ENDP

PROC Choose
@@loop:
in AL,60h
test AL,80h ; отжата - ждем
jnz @@loop
cmp AL,1 ; Esc - выход
jne @@1
sti
jmp return_real
@@1:
cmp AL,28 ; Enter - возврат
jne @@loop
ret
ENDP

saovu вне форума   Ответить с цитированием
Реклама