Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга. Гуржій. 1.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
3.53 Mб
Скачать

Int09 proc near

int 60h ;виклик «прихованого старого» об-

;роблювача переривання INT09h ; зберегти регістри в стеку

pushf

push ax

push ds

push si

push bx

;адресуємось до змінної голови буфера клавіатури BIOS mov ax, 0040h

mov ds, ax

mov si, ds:[lAh]

mov ax, [si]

; перевіряємо символ буфера на Alt + Буква cmp al, 0 ;перевіряємо: кінець макроса? jnz ExitProgram

CheckAltU:

cmp ah, 16h ;перевіряємо: натиснути ALT+U

;(код 16h у старшому байті)?

jnz CheckAltW

mov bx, & AltU

jmp LoadBuf

CheckAltW:

cmp ah, llh ;перевіряємо: натиснути ALT+W

;(код llh у старшому байті)? jnz CheckAltD mov bx, & AltW jmp LoadBuf

CheckAltD:

cmp ah, 20h ;перевіряємо: натиснути ALT+D

;(код 20h у старшому байті)?

jnz ExitProgram

mov bx, & AltD

jmp LoadBuf

;якщо так, то замінити на макрос

LoadBuf:

mov ds:[lCh], si

LoadBufLoop:

mov al, cs:[bx]

cmp al, 0

jz ExitLoadBuf

mov [si], al

mov B[si+l],0

inc bx

add si, 2

cmp si, 3Ch

jbe LoadBufLoop

mov si, lEh

jmp LoadBufLoop

ExitLoadBuf:

;розміщення покажчиків буфера клавіатури в BIOS

mov ds:[001Ch], si

ExitProgram:

; відновити регістри із стека

pop bx

pop si

pop ds

pop ax

popf

iret

ENDP

SetVectorlnterrupt:

;=======[ Встановлення 09-го вектора ]===========

cli

push ds

mov ax, 0

mov ds, ax

mov si, 09h * 4

;—[Зберігаємо старий вектор у змінній OLD09 ;та «ховаємо» його в]—

;—[таблиці векторів переривання під номером ; 60h]—

mov ax, [si] mov W cs:OLD09, ax mov ax, [si+2] mov W cs:OLD09+2, ax mov ax, [si]

mov ds:[60h*4], ax mov ax, [si+2]

mov ds:[60h*4+2], ax

Проблеми в системі переривання

У заняттях 7 та 8 розглядались обов'язкові вимоги, які повинні задовольняти програму оброблювача перери­вання. Обговорювались методи попередження повторного входження у власну TSR. При цьому вказувалось, що найпростіше блокувати повторне входження, викорис­товуючи зовнішню змінну-семафор, що набуває два значен­ня: (0) та (1). Перед входженням в TSR перевіряємо прапо­рець і, якщо він дорівнює 1, то входження в резидентну програму не виконується. У протилежному випадку прапорець встановлюється на 1 та викликається TSR. Але для надійно працюючої програми цього не достатньо. Досить часто можна спостерігати повторне входження в DOS. При цьому відомо, що MS-DOS не є реєнтабельною.

Розв'яжіть проблему

Ситуація

Необхідно написати високонадійну резидентну програму, в якій виключена можливість повторного входження в MS-DOS.

Відомі факти

Реєнтабельна програма — це програма, яка дозволяє, в силу особливостей своєї побудови, починати її виконання кілька разів, не чекаючи завершення виконання (виходу) програми, початого раніше. Реєнтабельна програма не змінює ні однієї константи або змінної, які можуть вплинути на повторне виконання програми. Більшість програм, що утворюють ядро MS-DOS, не є реєнтабельними. У зв'язку з цим не є реєнтабельними і програми, що звертаються до функцій MS-DOS безпосередньо або через функції бібліотеки мови C++.

Для TSR, що написана мовою C++ і застосовує бібліотечні функції, завжди !!! існує вірогідність повторного входження в MS-DOS, так як TSR може отримати керування в будь-який момент, у тому числі і тоді, коли MS-DOS виконує нереєнтабельну секцію свого коду.

Ваше розв'язання

Приблизний хід міркувань Причина проблеми

У силу вказаних вище фактів, причиною проблем, що виникають при повторному входженні TSR в MS-DOS, є нереєнтабельність програм операційної системи та вірогідний характер передачі керування Вашій TSR.

Можливі розв'язки

Для попередження повторного входження TSR в MS-DOS необхідно вимагати від ISR активізації TSR тільки тоді, коли MS-DOS дозволяє повторне входження. Реалі­зувати цю вимогу можна двома способами:

  1. використовувати переривання INT28h;

  1. використовувати прапорець повторного входження в MS-DOS.

Механізм переривання 28h, який часто називають «секретом переривання 28h», такий: як відомо, MS-DOS має утиліти «фонового» або псевдопаралельного виконання. Наприклад, PRINT.COM дозволяє друкувати файли та виконувати іншу програму. Утиліти паралельного вико­нання перехоплюють переривання 28h. Для того, щоб паралельна програма періодично отримувала керування, MS-DOS в ті моменти, коли вона виконує цикл очікування вводу з клавіатури та перед виконанням функцій з номе­рами від 00h до OCh, видає переривання 28h. Якщо ввімк­нути власну ISR в каскад оброблювачів переривання 28h, вона буде періодично отримувати керування та аналізувати можливість активізації TSR, наприклад, за станом прапор­ця, яким керує ще одна ISR.

Інший спосіб запобігання повторного входження в MS-DOS полягає у використанні прапорця повторного вход­ження. Адреса цього прапорця повертає в ES:BX функцію 34h переривання INT21h. Якщо MS-DOS знаходиться в нереєнтабельній секції свого коду, прапорець повторного входження дорівнює 1. Якщо ж MS-DOS виконує реєнта-бельну секцію, то прапорець дорівнює 0 та резидентна програма може безпечно активізуватись та використовувати у своїй роботі всі функції операційної системи.

Вплив Вашого розв'язання на вийняток повторного входження в MSDOS та ефективність резидентного оброблювача переривання

Цінність першого підходу полягає в тому, що коли викликається переривання 28h, є гарантія, що MS-DOS знаходиться в безпечному для повторного входження стані та можна сміливо активізувати TSR. Єдине обмеження, що накладається на TSR, яка отримує керування із пере­ривання 28h, полягає в забороні на використання функцій MS-DOS від OOh до OCh. Ігнорування цієї вимоги призво­дить до «зависання» системи.

Недолік іншого підходу полягає в тому, що рішення не активізувати TSR приймається незалежно від того, яку функцію виконує MS-DOS на даний момент часу. Хоча якщо прапорець повторного входження дорівнює 1, a MS-DOS виконує функції консольного вводу/виводу, у цей момент можна абсолютно безпечно використовувати функції доступу до файлів. Тому цей підхід можна підсилити, якщо передбачи­ти ISR-фільтр на переривання 21h і таким чином зменшити затримку між настанням моменту активізації TSR та її фактичною активізацією.