цветного видеоадаптера MONO_LOW EQU 0000
байт физического адреса ; сегмента видеопамяти ; цветного видеоадаптера MONO_LOW EQU 0000 ; мл. байт физического адреса ; сегмента видеопамяти ; монохромного видеоадаптера
CRT_SEG EQU 0Bh ; ст. байт физического адреса ; сегмента видеопамяти
; Селекторы, определённые в таблице GDT
DS_DESCR = (gdt_ds - gdt_0) CS_DESCR = (gdt_cs - gdt_0) SS_DESCR = (gdt_ss - gdt_0) BIOS_DESCR = (gdt_bio - gdt_0) CRT_DESCR = (gdt_crt - gdt_0) MDA_DESCR = (gdt_mda - gdt_0)
CMOS_PORT EQU 70h ; порт для доступа к CMOS-памяти PORT_6845 EQU 0063h ; адрес области данных BIOS, ; где записано значение адреса ; порта контроллера 6845 COLOR_PORT EQU 03d4h ; порт цветного видеоконтроллера MONO_PORT EQU 03b4h ; порт монохромного видеоконтроллера STATUS_PORT EQU 64h ; порт состояния клавиатуры SHUT_DOWN EQU 0feh ; команда сброса процессора VIRTUAL_MODE EQU 0001h ; бит перехода в защищённый режим A20_PORT EQU 0d1h ; команда управления линией A20 A20_ON EQU 0dfh ; открыть A20 A20_OFF EQU 0ddh ; закрыть A20 KBD_PORT_A EQU 60h ; адреса клавиатурных KBD_PORT_B EQU 61h ; портов INT_MASK_PORT EQU 21h ; порт для маскирования прерываний
STACK STACK_SIZE ; сегмент стека
DATASEG ; начало сегмента данных
DSEG_BEG = THIS WORD
; Память для хранения регистров SS, SP, ES. Содержимое ; этих регистров будет записано здесь перед входом в ; защищённый режим и восстановлено отсюда после возврата ; из защищённого режима в реальный.
real_ss dw ? real_sp dw ? real_es dw ?
; Глобальная таблица дескрипторов GDT, ; содержит следующие дескрипторы: ; ; gdt_0 - дескриптор для пустого селектора ; gdt_gdt - дескриптор для GDT ; gdt_ds - дескриптор для сегмента, адресуемого DS ; gdt_cs - дескриптор для сегмента кода ; gdt_ss - дескриптор для сегмента стека ; gdt_bio - дескриптор для области данных BIOS ; gdt_crt - дескриптор для видеопамяти цветного дисплея ; gdt_mda - дескриптор для видеопамяти монохромного дисплея
GDT_BEG = $ LABEL gdtr WORD
gdt_0 desc_struc <0,0,0,0,0> gdt_gdt desc_struc <GDT_SIZE-1,,,DATA_ACC,0> gdt_ds desc_struc <DSEG_SIZE-1,,,DATA_ACC,0> gdt_cs desc_struc <CSEG_SIZE-1,,,CODE_ACC,0> gdt_ss desc_struc <STACK_SIZE-1,,,DATA_ACC,0> gdt_bio desc_struc <B_DATA_SIZE-1,B_DATA_ADDR,0,DATA_ACC,0> gdt_crt desc_struc <CRT_SIZE-1,CRT_LOW,CRT_SEG,DATA_ACC,0> gdt_mda desc_struc <MONO_SIZE-1,MONO_LOW,CRT_SEG,DATA_ACC,0>
GDT_SIZE = ($ - GDT_BEG) ; размер таблицы дескрипторов
CODESEG ; сегмент кода
PROC start
; Инициализируем регистр сегмента данных ; для реального режима
mov ax,DGROUP mov ds,ax
; Определяем базовый адрес видеопамяти
call set_crt_base
; Стираем экран дисплея (устанавливаем серый фон)
mov bh, 77h call clrscr
; Выполняем все подготовительные действия для перехода ; в защищённый режим и обеспечения возможности возврата ; в реальный режим
call init_protected_mode
; Переключаемся в защищённый режим
call set_protected_mode
; --------- * Программа работает в защищённом режиме! * ---------
call write_hello_msg ; выводим сообщение на экран call pause ; ждём некоторое время
; Возвращаемся в реальный режим
call set_real_mode
; --------- * Программа работает в реальном режиме! * ---------
; Стираем экран и возвращаемся в DOS mov bh, 07h call clrscr mov ah,4Ch int 21h
ENDP start
; ------------------------------------------------------------ ; Макрокоманда для записи в дескриптор 24-битового ; базового адреса сегмента ; ------------------------------------------------------------
MACRO setgdtentry mov [(desc_struc bx).base_l],ax mov [(desc_struc bx).base_h],dl ENDM
; ------------------------------------------------------------ ; Процедура подготовки процессора к переходу в защищённый ; режим с последующим возвратом в реальный режим ; ------------------------------------------------------------
PROC init_protected_mode NEAR
; Заполняем глобальную таблицу дескрипторов GDT
; Вычисляем 24-битовый базовый адрес сегмента данных
mov ax,DGROUP mov dl,ah shr dl,4 shl ax,4
; Регистры dl:ax содержат базовый адрес, сохраняем его в di:si
mov si,ax mov di,dx
; Подготавливаем дескриптор для GDT
add ax,OFFSET gdtr adc dl,0 mov bx,OFFSET gdt_gdt setgdtentry
; Подготавливаем дескриптор для сегмента ds
mov bx,OFFSET gdt_ds mov ax,si mov dx,di setgdtentry
; Подготавливаем дескриптор для сегмента cs
mov bx,OFFSET gdt_cs mov ax,cs mov dl,ah shr dl,4 shl ax,4 setgdtentry
; Подготавливаем дескриптор для сегмента стека
mov bx,OFFSET gdt_ss mov ax,ss mov dl,ah shr dl,4 shl ax,4 setgdtentry
; Записываем адрес возврата в реальный режим в область ; данных BIOS по адресу 0040h:0067h
push ds mov ax,40 mov ds,ax mov [WORD 67],OFFSET shutdown_return mov [WORD 69],cs pop ds
; Маскируем все прерывания, в том числе немаскируемые. ; Записываем в CMOS-память в ячейку 0Fh код 5, ; этот код обеспечит после выполнения сброса процессора ; передачу управления по адресу, подготовленному нами ; в области данных BIOS по адресу 0040h:0067h. ; Для того, чтобы немаскируемые прерывания были запрещены, ; устанавливаем в 1 старший бит при определении ячейки CMOS.
Содержание Назад Вперед
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий