Операційна система ms-dos

Для обробки подій, що відбуваються асинхронно по відношенню до виконання програми, найкраще підходить механізм переривань. Переривання можна розглядати як деякий особлива подія в системі, що вимагає моментальної реакції. Наприклад, добре спроектовані системи підвищеної надійності використовують переривання по аварії в мережі живлення для виконання процедур запису вмісту регістрів і оперативної пам'яті на магнітний носій з тим, щоб після відновлення живлення можна було продовжити роботу з того ж місця.

Здається очевидним, що можливі найрізноманітніші переривання з найрізноманітніших причин. Тому переривання розглядається не просто як таке: з ним пов'язують число, зване номером типу переривання або просто номером переривання. З кожним номером переривання зв'язується ту чи іншу подію. Система вміє розпізнавати, яке переривання, з яким номером вони є, а запускає відповідну цим номером процедуру.

Програми можуть самі викликати переривання з заданим номером. Для цього вони використовують команду INT. Це так звані програмні переривання. Програмні переривання не є асинхронними, так як викликаються з програми (а вона-то знає, коли вона викликає переривання!).

Використання переривань при роботі з повільними зовнішніми пристроями дозволяють поєднати введення / виведення з обробкою даних в центральному процесорі і в результаті підвищує загальну продуктивність системи.

Деякі переривання (перші п'ять в порядку номерів) зарезервовані для використання самим центральним процесором на випадок будь-яких особливих подій на кшталт спроби поділу на нуль, переповнення і т.п.

Іноді бажано зробити систему нечутливою до всіх або окремих переривань. Для цього використовують так зване маскування переривань, про який ми ще будемо докладно говорити. Але деякі переривання замаскувати не можна, це немасковані переривання.

Зауважимо ще, що обробники переривань можуть самі викликати програмні переривання, наприклад, для отримання доступу до сервісу BIOS або DOS (сервіс BIOS також доступний через механізм програмних переривань).

Складання власних програм обробки переривань і заміна стандартних обробників DOS і BIOS є відповідальною і складною роботою. Необхідно враховувати всі тонкощі роботи апаратури і взаємодії програмного і апаратного забезпечення. При налагодженні можливе руйнування операційної системи з непередбачуваними наслідками, тому треба дуже уважно стежити за тим, що робить Ваша програма.

Ініціалізація таблиці відбувається частково BIOSпосле тестування апаратури і перед початком завантаження операційної системою, частково при завантаженні DOS. DOS може переключити на себе деякі переривання BIOS.

Займемося тепер вмістом таблиці векторів переривань. Наведемо призначення деяких найбільш важливих векторів:

Переривання покрокового режиму. Виробляється після виконання кожної машинної команди, якщо в слові прапорів встановлений біт покрокової трасування TF. Використовується для налагодження програм. Це переривання не виробляється після виконання команди MOV в сегментні регістри або після завантаження сегментних регістрів командою POP.

Апаратне немаскируемое переривання. Це переривання може використовуватися по-різному в різних машинах. Зазвичай виробляється при помилку парності в оперативній пам'яті і при запиті переривання від співпроцесора.

Переривання для трасування. Це переривання генерується при виконанні однобайтового машинної команди з кодом CCh і зазвичай використовується отладчиками для установки точки переривання.

Переповнення. Генерується машинною командою INTO, якщо встановлений прапор OF. Якщо прапор не встановлений, то команда INTO виконується як NOP. Це переривання використовується для обробки помилок при виконанні арифметичних операцій.

Друк копії екрану. Генерується при натисканні на клавіатурі клавіші PrtScr. Зазвичай використовується для друку способу екрану. Для процесора 80286 генерується при виконанні машинної команди BOUND, якщо перевіряється значення вийшло за межі заданого діапазону.

Невизначений код операції або довжина команди більше 10 байт (для процесора 80286).

IRQ0 - IRQ15 - це апаратні переривання, про них буде розказано пізніше.

Часто при виконанні критичних ділянок програм, для того щоб гарантувати виконання певної послідовності команд цілком, доводиться забороняти переривання. Це можна зробити командою CLI. Її потрібно помістити в початок критичної послідовності команд, а в кінці розташувати команду STI, роздільну процесору сприймати переривання. Команда CLI забороняє тільки маскуються переривання, немасковані завжди обробляються процесором.

Якщо ви використовуєте заборона переривань за допомогою команди CLI, стежте за тим, щоб переривання НЕ відключалися на тривалий період часу, так як це може призвести до небажаних наслідків. Наприклад, будуть відставати годинник.

Якщо вам треба заборонити не всі переривання, а тільки деякі, наприклад, від клавіатури, то для цього треба скористатися послугами контролера переривань. Детально про це трохи нижче, зараз відзначимо лише, що видачею в цей контролер певної керуючої інформації можна замаскувати переривання від окремих пристроїв.

Вашій програмі може знадобитися організувати обробку деяких переривань. Для цього програма повинна перепризначити вектор на свій обробник. Це можна зробити, змінивши вміст відповідного елемента таблиці векторів переривань.

Дуже важливо не забути перед завершенням роботи відновити вміст змінених векторів в таблиці переривань, тому що після завершення роботи програми пам'ять, яка була їй розподілена, вважається вільною і може бути використана для завантаження іншої програми. Якщо ви забули відновити вектор і прийшло переривання, то система може зруйнуватися - вектор тепер вказує на область, яка може містити що завгодно.

Функція 25h переривання 21h встановлює для вектора з номером, що знаходяться в AL, обробник переривання DS: DX.

Зрозуміло, ви можете безпосередньо звертатися до таблиці векторів переривань, але тоді під час запису необхідно замаскувати переривання командою CLI, не забувши дозволити їх після запису командою STI.

Якщо вам треба додати будь-які власні дії до тих, що виконує стандартний обробник переривання, то можна організувати ланцюжок перерваний.

У бібліотеці Quick C є функція для організації ланцюжка переривань - _chain_intr ().

Розглянемо більш докладно можливості бібліотеки інтегрованого середовища Quick C, призначені для роботи з перериваннями.

Модифікатор interrupt (_interrupt для Quick C 2.5 і C 6.0) описує функцію, яка є обробником переривання. Така функція завершується командою повернення з обробки переривання IRET, і для неї автоматично генеруються команди збереження регістрів на вході і їх відновлення при виході з обробника переривання. Приклад використання модифікатора для опису функції обробки переривання:

Ключове слово interrupt використовується також для опису змінних, призначених для зберігання векторів переривань:

Модифікатори _interrupt і _far для Quick C 2.5 і C 6.0 є синонімами відповідно interrupt і far.

Які вимоги пред'являються до програми обробки переривання?

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

Для установки свого обробника переривань використовуйте функцію _dos_setvec. Ця функція має два параметри - номер переривання і покажчик на нову функцію обробки переривання. наприклад:

У цьому прикладі для клавіатурного переривання з номером 16h встановлюється новий обробник переривання my_key_intr.

Наступний простий приклад ілюструє застосування всіх трьох функцій, призначених для роботи з перериваннями. Ця програма вбудовує власний обробник переривання таймера, який буде викликатися приблизно 18,2 рази в секунду. Вбудований обробник переривання вважає тики таймера і, якщо значення лічильника кратно 20, на динамік комп'ютера видається звуковий сигнал. В кінці роботи нова програма обробки переривання таймера викликає старий оброблювач за допомогою функції _chain_intr.

Після установки нового обробника переривання таймера основна програма чекає натискання на клавіатурі будь-яку клавішу, потім вона відновлює старе вміст вектора переривання.

Апаратні переривання виробляються пристроями комп'ютера, коли виникає необхідність їх обслуговування. Наприклад, по перериванню таймера відповідний обробник переривання збільшує вміст комірок пам'яті, використовуваних для зберігання часу. На відміну від програмних переривань, що викликаються заплановано самої прикладної програмою, апаратні переривання завжди відбуваються асинхронно по відношенню до що виконується програмами. Крім того, може виникнути одночасно відразу кілька переривань!

Для того, щоб система "не розгубилася", вирішуючи яке переривання обслуговувати в першу чергу, існує спеціальна схема пріоритетів. Кожному переривання призначається свій унікальний пріоритет. Якщо відбувається одночасно кілька переривань, то система віддає перевагу самому високопріоритетних, відкладаючи на час обробку інших переривань.

Система пріоритетів реалізована на двох мікросхемах Intel 8259 (для машин класу XT - на одній такій мікросхемі). Кожна мікросхема обслуговує до восьми пріоритетів. Мікросхеми можна об'єднувати (каскадировать) для збільшення кількості рівнів пріоритетів в системі.

Рівні пріоритетів позначаються скорочено IRQ0 - IRQ15 (для машин класу XT існують тільки рівні IRQ0 - IRQ7).

Для машин XT пріоритети лінійно залежали від номера рівня переривання. IRQ0 відповідало найвищим пріоритетом, за ним йшли IRQ1, IRQ2, IRQ3 і так далі. Рівень IRQ2 в машинах класу XT був зарезервований для подальшого розширення системи і, починаючи з машин класу AT, IRQ2 став використовуватися для каскадування контролерів переривання 8259. Додані пріоритетні рівні IRQ8 - IRQ15 в цих машинах розташовуються по пріоритету між IRQ1 і IRQ3.

Наведемо таблицю апаратних переривань, розташованих в порядку пріоритету:

IRQ7 - переривання принтера. Генерується принтером, коли він готовий до виконання чергової операції. Багато адаптери принтера не використовують це переривання.

З таблиці видно, що найвищий пріоритет у переривань від таймер, потім йде переривання від клавіатури.

Для управління схемами пріоритетів необхідно знати внутрішній устрій контролера переривань 8259. Вступники переривання запам'ятовуються в регістрі запиту на переривання IRR. Кожен біт з восьми в цьому регістрі відповідає перериванню. Після перевірки на обробку зараз іншого переривання запитується інформація з регістра обслуговування ISR. Перед видачею запиту на переривання в процесор перевіряється вміст восьмибитового регістра маски переривань IMR. Якщо переривання даного рівня не замасковано, то видається запит на переривання.

Найбільш цікавими з точки зору програмування контролера переривань є регістри маски переривань IMR і керуючий регістр переривань.

Розряди регістра маски переривань відповідають номерам IRQ. Для того щоб замаскувати апаратне переривання будь-якого рівня, треба заслати в регістр маски байт, в якому біт, що відповідає цьому рівню, встановлений в 1. Наприклад, для маскування переривань від НГМД в порт 21h треба заслати двійковечисло 01000000.

Наведемо приклад програми, що маскує переривання від флоппі-диска:

Ця програма є на дискеті, що додається до книги. Запустіть її (з жорсткого диска) і спробуйте попрацювати, наприклад, з дисководом А. У вас нічого не вийде!

Щоб "оживити" флоппі-диски, запустіть програму, яка размаскірует все переривання (в тому числі і від флоппі):

Зауважте, що ми тільки що замаскували переривання саме від флоппі-диска, всі інші пристрої продовжували нормально працювати. Якби ми видали машинну команду CLI, то відключилися б все апаратні переривання. Це призвело б, наприклад, до того, що клавіатура була б заблокована.

Якщо ви обробляєте переривання 1Ch, то добавка в кінці програми не потрібна, так як це переривання є розширенням іншого переривання (переривання таймера).

Перед тим, як завершити вивчення переривань, задамося питанням - чи можна замаскувати немаскируемое переривання? Виявляється можна!

Звичайно, якщо сигнал переривання прийшов на вхід немаскируемого переривання процесора, нічого зробити не можна - переривання відбудеться неминуче. Але в комп'ютерах XT і AT передбачені схеми, що блокують вхід немаскируемого переривання процесора NMI.

Аналогічно для AT маскированием немаскируемого переривання управляє біт 7 порту 70h. Запис байта 0ADh в порт 70h заборонить немаскируемое переривання, а байта 2Dh - дозволить проходження переривання.

Зауважимо, що ми не забороняємо немаскируемое переривання "всередині" процесора - це неможливо за визначенням, ми "не пускаємо" сигнал переривання на вхід NMI.

Схожі статті