mov [protect_sel], dx ; перехода far jmp
; Подготовка к возврату в реальный режим
push ds ; готовим адрес возврата
mov ax,40h ; из защищённого режима
mov ds,ax
mov [WORD 67h],OFFSET shutdown_return
mov [WORD 69h],cs
pop ds
; Запрещаем и маскируем все прерывания
cli
in al, INT_MASK_PORT
and al, 0ffh
out INT_MASK_PORT, al
; Записываем код возврата в CMOS-память
mov al,8f
out CMOS_PORT,al
jmp delay1
delay1:
mov al,5
out CMOS_PORT+1,al
call enable_a20 ; открываем линию A20
mov [real_ss],ss ; запоминаем регистры SS и ES
mov [real_es],es
; Перепрограммируем контроллер прерываний
; для работы в защищённом режиме
mov dx,MASTER8259A
mov ah,20
call set_int_ctrlr
mov dx,SLAVE8259A
mov ah,28
call set_int_ctrlr
; Загружаем регистры IDTR и GDTR
lidt [FWORD idtr]
lgdt [QWORD gdt_ptr]
mov ax, 0001h ; переключаем процессор
lmsw ax ; в защищённый режим
; jmp far flush
db 0eah
dw OFFSET flush
p_mode_select dw ?
LABEL flush FAR
mov dx, [protect_sel]
mov ss, dx
mov ds, dx
mov es, dx
; Обнуляем содержимое регистра LDTR
mov ax, 0
lldt ax
pop bp
ret
ENDP _protected_mode
; ----------------------------------------------------
; Возврат в реальный режим.
; Прототип для вызова
; void real_mode();
; ----------------------------------------------------
PROC _real_mode NEAR
; Сброс процессора
cli
mov [real_sp], sp
mov al, SHUT_DOWN
out STATUS_PORT, al
rmode_wait:
hlt
jmp rmode_wait
LABEL shutdown_return FAR
; Вернулись в реальный режим
mov ax, DGROUP
mov ds, ax
assume ds:DGROUP
mov ss,[real_ss]
mov sp,[real_sp]
in al, INT_MASK_PORT
and al, 0
out INT_MASK_PORT, al
call disable_a20
mov ax, DGROUP
mov ds, ax
mov ss, ax
mov es, ax
mov ax,000dh
out CMOS_PORT,al
sti
ret
ENDP _real_mode
; -------------------------------------------------------
; Загрузка регистра TR.
; Прототип для вызова:
; void load_task_register(unsigned int tss_selector);
; -------------------------------------------------------
PROC _load_task_register NEAR
push bp
mov bp,sp
ltr [bp+4] ; селектор для текущей задачи
pop bp
ret
ENDP _load_task_register
; -------------------------------------------------------
; Переключение на задачу.
; Прототип для вызова:
; void jump_to_task(unsigned int tss_selector);
; -------------------------------------------------------
PROC _jump_to_task NEAR
push bp
mov bp,sp
mov ax,[bp+4] ; получаем селектор
; новой задачи
mov [new_select],ax ; запоминаем его
jmp [DWORD new_task] ; переключаемся на
; новую задачу
pop bp
ret
ENDP _jump_to_task
; ------------------------------
; Открываем линию A20
; ------------------------------
PROC enable_a20 NEAR
push ax
mov al, A20_PORT
out STATUS_PORT, al
mov al, A20_ON
out KBD_PORT_A, al
pop ax
ret
ENDP enable_a20
; ------------------------------
; Закрываем линию A20
; ------------------------------
PROC disable_a20 NEAR
push ax
mov al, A20_PORT
out STATUS_PORT, al
mov al ,A20_OFF
out KBD_PORT_A, al
pop ax
ret
ENDP disable_a20
; -----------------------------------------------------------
; Готовим структуру для загрузки регистра IDTR
; Прототип для вызова функции:
; void load_idtr(unsigned long idt_ptr, word idt_size);
; -----------------------------------------------------------
PROC _load_idtr NEAR
push bp
mov bp,sp
mov ax,[bp+4] ; мл. слово адреса IDT
mov dx,[bp+6] ; ст. слово адреса IDT
mov bx, OFFSET idtr
; Запоминаем адрес IDTR в структуре
mov [(idtr_struc bx).idt_low], ax
mov [(idtr_struc bx).idt_hi], dl
; Получаем предел IDT и запоминаем его в структуре
mov ax, [bp+8]
mov [(idtr_struc bx).idt_len], ax
pop bp
ret
ENDP _load_idtr
; ----------------------------------
; Установка контроллера прерываний
; ----------------------------------
PROC set_int_ctrlr NEAR
mov al, 11
out dx, al
jmp SHORT $+2
mov al, ah
inc dx
out dx, al
jmp SHORT $+2
mov al, 4
out dx, al
jmp SHORT $+2
mov al, 1
out dx, al
jmp SHORT $+2
mov al, 0ffh
out dx, al
dec dx
ret
ENDP set_int_ctrlr
; --------------------------
; Выдача звукового сигнала
; --------------------------
PROC _beep NEAR
push ax bx cx
in al,KBD_PORT_B
push ax
mov cx,80
beep0:
push cx
and al,11111100b
out KBD_PORT_B,al
mov cx,60
idle1:
loop idle1
or al,00000010b
out KBD_PORT_B,al
mov cx,60
idle2:
loop idle2
pop cx
loop beep0
pop ax
out KBD_PORT_B,al
pop cx bx ax
ret
ENDP _beep
; -------------------------------
; Задержка выполнения программы
; -------------------------------
PROC _pause NEAR
push cx
mov cx,10
ploop0:
push cx
xor cx,cx
ploop1:
loop ploop1
pop cx
loop ploop0
pop cx
ret
ENDP _pause
; -----------------------
; Размаскирование прерываний
; -----------------------
PROC _enable_interrupt NEAR
in al, INT_MASK_PORT
and al, 0fch
out INT_MASK_PORT, al
sti
ret
ENDP _enable_interrupt
end
Процессоры семейства Intel x86 реализуют необходимые средства для организации мультизадачных ОС с разделением адресного пространства и виртуальной памяти.
В процессе написания данного курсового проекта мной были изучена организация работы защищенного режима процессоров 80286, адресация ими свыше 1 Мб памяти, работа с прерываниями в защищенном режиме процессора, организация мультизадачных операционных систем.
- «Защищенный режим процессоров Intel 80286/80386/80486» © Александр Фролов, Григорий Фролов Том 6, М.: Диалог-МИФИ, 1993, 234 стр.
- «MS-DOS для программиста» © Александр Фролов, Григорий Фролов Том 18, часть 1, М.: Диалог-МИФИ, 1995, 254 стр.
- «MS-DOS для программиста» © Александр Фролов, Григорий Фролов Том 19, часть 2, М.: Диалог-МИФИ, 1995, 253 стр.
- «Язык Ассемблера для IBM PC и программирования» © Питер Абель, М.: «Высшая школа», Москва, 1992, 444 стр.
- «Язык программирования для персонального компьютера Си», © С.О. Бочков, Д.М. Субботин, М.: Диалог-МИФИ, 1990, 383 стр.
- Материалы WEB-сервера для разработчиков фирмы Intel http://developer.intel.com
)