Смекни!
smekni.com

Робота в захищеному режимі мікропроцесора (стр. 4 из 5)

mov excep,7

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_08;assembler; { Обработчик исключения 8: }

asm { двойная ошибка }

mov excep,8

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_10;assembler; { Обработчик исключения 10: }

asm { недоступен TSS }

mov excep,10

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_11;assembler; { Обработчик исключения 11: }

asm { недоступен сегмент }

mov excep,11

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_12;assembler; { Обработчик исключения 12: }

asm { ошибка доступа к сегменту стека }

mov excep,12

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_13;assembler; { Обработчик исключения 13: }

asm { нарушение общей защиты }

mov excep,13

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_14;assembler; { Обработчик исключения 14: }

asm { недоступна страница }

mov excep,14

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_16;assembler; { Обработчик исключения 16: }

asm { ошибка FPU при NE=1 регистра CR0 }

mov excep,16

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_17;assembler; { Обработчик исключения 17: }

asm { ошибка выравнивания данных }

mov excep,17

int 32h

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

procedure exc_18;assembler; { Обработчик исключения 18: }

asm { ошибка функционирования узлов МП и МПС }

mov excep,18

cmp cpu_type,2

jz @1

db 0ffh,2eh

dw ofs_ret_mov

@1:db 9ah

dw offset reset

dw code_sel2

end;

{---------Обработчики-заглушки аппаратных прерываний,---------}

{----------поступающих на 1-й контроллер прерываний-----------}

procedure PIC_1;assembler;

asm

push ax

mov al,$20

out $20,al { Сброс бита регистра ISR 1-го ПКП }

pop ax

cmp cpu_type,2 { Если 80286 - разрядность 16, }

je @7 { иначе - 32 }

db 66h

@7:iret

end;

{---------Обработчики-заглушки аппаратных прерываний,---------}

{----------поступающих на 2-й контроллер прерываний-----------}

procedure PIC_2;assembler;

asm

push ax

mov al,$20 { Сброс бита регистра ISR }

out $20,al { 1-го и }

out $a0,al { и 2-го контроллеров прерываний }

pop ax

cmp cpu_type,2

je @8

db 66h

@8:iret

end;

procedure keyb;assembler; { Обработчик прерываний }

asm { от клавиатуры: }

mov al,20h

out 20h,al

in al,60h { Чтение скан-кода нажатия/отжатия клавиши }

test al,$80

jnz @k1 { Переход, если клавиша отжата }

mov scan,al

@k1:cmp cpu_type,2

je @k2

db 66h

@k2:iret

end;

procedure int_30h;assembler; { Обработчик программного }

asm { прерывания 30h: }

cmp ah,2 { AH - номер функции }

jz @i2 { Al - номер подфункции }

cmp ah,3 { BL - номер строки экрана }

jz @i3 { BH - номер столбца экрана }

cmp ah,4 { DL/DX/EDX - значение данных }

jz @i4 { (байта/слова/двойного слова) }

cmp ah,5 { CL - видео-атрибут }

jz @i5 { SI - смещение строки символов }

{ Функция 1: установка маркера в заданную точку экрана }

mov ax,bx

xor bh,bh

mov bl,ah

xor ah,ah

mov dl,80

mul dl

add ax,bx

shl ax,1

mov di,ax

jmp @end

@i2: { Функция 2: вывод символа на экран }

mov al,dl

mov ah,cl

stosw

jmp @end

@i3: { Функция 3: вывод данных на экран в 16-ричной форме }

{ AL=0 - вывод байта }

{ AL=1 -вывод слова }

{ AL=2 - вывод двойного слова }

lea bx,hex_tabl

mov ah,cl

cmp al,0

jz @8

cmp al,1

jz @16

add di,14

mov cx,8

jmp @1

@8:add di,2

mov cx,2

jmp @1

@16:add di,6

mov cx,4

@1:push cx

@lp:mov al,dl

and al,0fh

db 66h

shr dx,4

xlat

stosw

sub di,4

loop @lp

pop cx

shl cx,1

add cx,4 {2}

add di,cx

jmp @end

@i4: { Функция 4: вывод строки символов на экран }

mov ah,cl

mov bx,si

inc si

mov cl,[bx]

xor ch,ch

@wxy:

lodsb

stosw

loop @wxy

jmp @end

@i5: { Функция 5: вывод данных на экран в двоичной форме }

{ AL=0 - вывод байта }{ AL=1 -вывод слова }

{ AL=2 - вывод двойного слова }

{ lea bx,duo_tabl}

mov ah,cl

cmp al,0

jz @8_2

cmp al,1

jz @16_2

mov cx,8

jmp @2

@8_2:

mov cx,2

jmp @2

@16_2:

mov cx,4

@2:push cx

push cx

shl cx,3

sub cx,2

add di,cx { di+cx*8-2 }

pop cx

@lp_1:push cx

xor ah,8

mov cx,4

@lp_2:mov al,dl

and al,01h

db 66h

shr dx,1

xlat

stosw

sub di,4

loop @lp_2

pop cx

loop @lp_1

pop cx

shl cx,3

add cx,2 { di+cx*8+2 }

add di,cx

@end:db 66h

iret

end;

procedure int_30hr;assembler; { Обработчик программного }

asm { прерывания 30h: }

cmp ah,2 { AH - номер функции }

jz @i2 { Al - номер подфункции }

cmp ah,3 { BL - номер строки экрана }

jz @i3 { BH - номер столбца экрана }

cmp ah,4 { DL/DX/EDX - значение данных }

jz @i4 { (байта/слова/двойного слова) }

cmp ah,5 { CL - видео-атрибут }

jz @i5 { SI - смещение строки символов }

{ Функция 1: установка маркера в заданную точку экрана }

mov ax,bx

xor bh,bh

mov bl,ah

xor ah,ah

mov dl,80

mul dl

add ax,bx

shl ax,1

mov di,ax

jmp @end

@i2: { Функция 2: вывод символа на экран }

mov al,dl

mov ah,cl

stosw

jmp @end

@i3: { Функция 3: вывод данных на экран в 16-ричной форме }

{ AL=0 - вывод байта } { AL=1 -вывод слова }

{ AL=2 - вывод двойного слова }

lea bx,hex_tabl

mov ah,cl

cmp al,0

jz @8

cmp al,1

jz @16

add di,14

mov cx,8

jmp @1

@8:add di,2

mov cx,2

jmp @1

@16:add di,6

mov cx,4

@1:push cx

@lp:mov al,dl

and al,0fh

db 66h

shr dx,4

xlat

stosw

sub di,4

loop @lp

pop cx

shl cx,1

add cx,4 {2}

add di,cx

jmp @end

@i4: { Функция 4: вывод строки символов на экран }

mov ah,cl

mov bx,si

inc si

mov cl,[bx]

xor ch,ch

@wxy:

lodsb

stosw

loop @wxy

jmp @end

@i5: { Функция 5: вывод данных на экран в двоичной форме }

{ AL=0 - вывод байта }

{ AL=1 -вывод слова }

{ AL=2 - вывод двойного слова }

{ lea bx,duo_tabl}

mov ah,cl

cmp al,0

jz @8_2

cmp al,1

jz @16_2

mov cx,8

jmp @2

@8_2:

mov cx,2

jmp @2

@16_2:

mov cx,4

@2:push cx

push cx

shl cx,3

sub cx,2

add di,cx { di+cx*8-2 }

pop cx

@lp_1:push cx

xor ah,8

mov cx,4

@lp_2:mov al,dl

and al,01h

db 66h

shr dx,1

xlat

stosw

sub di,4

loop @lp_2

pop cx

loop @lp_1

pop cx

shl cx,3

add cx,2 { di+cx*8+2 }

add di,cx

@end: iret

end;

{------------------Вывод номера исключения--------------------}

procedure int_32h;assembler;

asm

mov ah,1 { Функция 1: установка маркера на экране }

mov bl,22 { с координатами - строка 22, }

mov bh,1 { столбец 1 }

int 30h

mov ah,4 { Функция 4: вывод на экран }

mov si, offset s2 { строки символов s2 }

mov cl,1ah { видеоатрибут }

int 30h

mov ax,300h { Функция 3, подфункция 0: }

mov dl,excep { вывод на экран номера исключения }

mov cl,1ch { видеоатрибут }

int 30h

db 66h

iret

end;

end.

(*16. а) Исключение, вызванное запретом чтения из сегмента кода б) Разработать обработчик прерывания от системного таймера, который каждые 5 секунд меняет цвет бордюра.

I. Вызвать требуемое в индивидуальном задании исключение.

II. Обработать это исключение одним из двух способов:

а) устранив причину исключения;

б) пропустив команду, вызвавшую исключение.

III. Обработать заданное внешнее прерывание.*)

program p_intr;

{ Обработка прерываний в защищенном режиме }

uses crt, prot; { Модуль PROT содержит константы, }

{ типы переменных, переменные, процедуры и функции }

{ для работы в защищенном режиме }

label ret_r; { Точка возврата в реальный режим }

const

s:string='Обработка исключений и прерываний в защищенном режиме';

s1:string='CS SS DS ES CR0 EFLAGS: ';

s2:string='Обработано исключение ';

s3:string='Na 5 tik timera menyaem cvet BORDURA.';

s4:string='Press Esc to exit';

var

cs_real, { Значение регистра CS в реальном режиме }

err, { Код ошибки }

lim1,lim2,count:word;

scan,i,al_,ah_,n_exc,row:byte;

sscan:byte;

eflags:longint;

quel,counter,color:byte;

dwd:word;

{--------------Разработка обработчиков исключений--------------}

procedure out_exc;assembler; { Вывод номера исключения }

asm

mov ah,1 { Функция 1: установка маркера на экране }

mov bl,22 { с координатами - строка 22, }

mov bh,1 { столбец 1 }

int 30h

mov ah,4 { Функция 4: вывод на экран }

mov si, offset s2 { строки символов s2 }

mov cl,1eh

int 30h

mov ax,300h { Функция 3, подфункция 0: }

mov dl,excep { вывод на экран номера исключения }

mov cl,1ch

int 30h

mov dx,dwd

ret

end;

procedure exc_00;assembler; { Обработчик исключения 0 }

{-----Два варианта устранения зацикливания обработки отказа----}

mov bl,1 { Вариант 1: устранение причины отказа }

pusha

(* push bp { Вариант 2: изменение в стеке значения }

mov bp,sp { счетчика команд IP на величину длины команды }

inc word ptr [bp+2]

pop bp *)

mov excep,0

call out_exc; { Вывод сообщения об обработке исключения }

popa

cmp cpu_type,2

jz @2

db 66h

@2:iret

end;

procedure exc_13;assembler; { Обработчик исключения 0 }

{-----Два варианта устранения зацикливания обработки отказа----}

asm

cmp cpu_type,2

jz @1

db 66h

@1:pop bx

{-------------Вариант 2: изменяет в стеке значение------------}

{-------------счетчика команд IP на длину команды,------------}

{-----------вызвавшей исключение (div bl - 1 байт)------------}

push bp

mov bp,sp

add word ptr [bp+2],4 { или inc word ptr [bp+2] }

pop bp

{---------------------Вывод сообщения-------------------------}

{---------о возникновении исключения с номером excep----------}

pusha

mov excep,13

int 32h

(*push bx

mov ax,501h { Функция 5: вывод на экран }

mov cl,1eh { кода ошибки в двоичной форме }

pop dx

int 30h *)

popa

{-------Вариант 3: выполняет выход из защищенного режима-------}

{----через межсегментный косвенный переход на метку ret_mov----}

(* db 0ffh,2eh

dw ofs_ret_mov *)

cmp cpu_type,2

jz @2

db 66h

@2:iret

end;

procedure exc_0b;assembler; { Обработчик исключения 11 }

{ вызывается при отсутствии сегмента в памяти и выполняет }

{ коррекцию дескриптора сегмента - востанавливает бит P }

asm

mov excep,0bh

cmp cpu_type,2

jz @1

db 66h

@1:pop bx { Чтение из стека кода ошибки }

mov err,bx { и запись в переменную err }

and bx,not 7 { Выделение смещения селектора }

add bx,offset gdt+5 { Выбор поля байта доступа в GDT }

push ax

mov al, [bx] { Чтение байта доступа сегмента }

or al,80h

mov [bx],al { Установка бита P=1 в байте доступа }

pop ax

cmp cpu_type,2

jz @2

db 66h

@2:iret

end;

procedure keyb;assembler; { Обработчик прерываний }

asm { от клавиатуры: }

mov al,20h

out 20h,al { Сброс контроллера прерываний }

in al,60h { Чтение скан-кода нажатия/отжатия клавиши }

test al,80h

jnz @1 { Переход, если клавиша отжата }

mov scan,al

@1:cmp cpu_type,2

jz @3

db 66h

@3:iret

end;

procedure ttim;assembler; { Обработчик прерываний }

asm { от timer: }

push ax

mov al,$20

out $20,al { Сброс бита регистра ISR 1-го ПКП }

pop ax

inc counter

cmp counter,5

jnz @99

mov counter,0

push dx

push ax

mov dx,3dah

in al,dx

mov dx,3c0h

mov al,11h

out dx,al

inc color

mov al,color