Асемблер (assembler)

Асемблер (assembler). Розробка резидентних обробників

Розробити резидент-уповільнювач виконання програм. Уповільнення реалізується процедурою затримки, вставленої в обробник переривання користувача таймером (int 1Ch). Ініціалізація резидента здійснюється за допомогою комбінації клавіш . Значення цифрової клавіші впливає на швидкість уповільнення.

2. Структура та опис розробки

Вся розробка складається з двох файлів: *.com – безпосередньо резидента та *.exe – демонстраційної програми. Розглянемо спочатку структуру та принцип дії резидента. До складу *.com файлу входять наступні обробники: користувальницький обробник new_1Ch, що замінює переривання 1Сh, користувальницький обробник клавіатури new_09h, що замінює системний обробник 09h, а також обробник new_2Fh, що замінює відповідне переривання. Також у файлі є додаткові поля та методи, необхідні для коректного функціонування резидента.

Розглянемо роботу користувальницького прикладного обробника переривань new_1Ch, що замінює на час роботи резидента прикладний апаратний обробник переривань DOS Int 1Ch, що входить до складу системного обробника BIOS 08h Переривання DOS Int 1Ch служить для перехоплення тактів системного таймера (1ц містить лише одну команду Iret. Новий обробник містить алгоритм уповільнення виконання програм, що ґрунтується на тому факті, що переривання 1Ch викликається приблизно 18 разів на секунду. Виходить, кожен дзвінок відбувається приблизно через кожні 55 мс. Таким чином можна для уповільнення виконання програм пропускати кожні n-і виклики, а решту затримувати спеціальним алгоритмом. Отримуємо уповільнювач в n раз виконання програм, де n- це коефіцієнт уповільнення,який регулюється змінною cnt, що знаходиться в кодовому сегменті. Ця змінна може набувати значень від 0 до 8. Слід додати, що обробник new_1Ch несе ще одну функцію – демонстраційну. Він виводить на екран неуповільнений системний час. Це означає, що в будь-якому режимі уповільнення обробник не знаходився б, на екрані буде відображатися системний час. Розглянемо тепер роботу алгоритму затримки. При черговому виклику обробника new_1Ch відбувається перевірка режиму сповільнювача. Режим роботи характеризується станом змінної fn, що у кодовому сегменті. Ця змінна може набувати значення від 0 до 8. Значення змінної “0” відповідає “прихованому” режиму роботи, у якому на екран не виводиться системний час, і навіть немає уповільнення. Значення змінної від 1 до 8 характеризують відповідний коефіцієнт затримки при системному часі, що виводиться на екран. Отже, при встановленні режиму роботи резидента (за замовчуванням йде 0), відбувається виставлення в змінну cnt, що зберігається там коефіцієнта уповільнення, а так само за режимом роботи визначається виводити або ні на екран системного часу. Коефіцієнт уповільнення - це кількість викликів процедури затримки виконання програми, час виконання якої приблизно дорівнює 55 мс. Далі відбувається аналіз змінної f1 на той факт, що робить цього разу: прохід на Iret, або ж проводити затримку виконання. Якщо fn==0, то йдемо на вихід і виставляємо fn=1, якщо fn==1, то запускаємо алгоритм затримки з можливістю виведення системного або без нього. По завершенню роботи алгоритму fn виставляється 0, тобто. при наступному виклику оброблювача затримки не відбуватиметься.

Варто зауважити, що змінна fn, що характеризує режим роботи резидентазнаходиться хоч і сегмент коду, але не в межах функції new_1Ch, а поза нею. Це потрібно для загальнодоступності цієї змінної, т.к. її використовує користувальницький обробник new_09h для виставлення режиму роботи, а також обробник new_2Fh для його зчитування.

Мультиплексне переривання new_2Fh працює за наступним принципом: спочатку перевіряється вміст регістру ax на запит режиму роботи резидента, якщо такий запит має місце, то повертається вміст змінної fn у тому ж регістрі та відбувається вихід із процедури. Якщо такого запиту не надійшло, то аналіз того ж регістру на наявність нашої функції в пам'яті. Варто зазначити, що функцією надано ідентифікатор 0C88h. За наявності резидента в пам'яті відбудеться повернення в молодшому байті регістра ax значення 0ffh. Якщо цього запиту не надійшло, то перевіряється наявність запиту на деінсталяцію. При позитивному результаті відбувається відновлення всіх раніше перехоплених векторів та вивантаження з пам'яті резидента разом із PSP. За відсутності всіх вище перелічених запитів відбудеться перехід у наступний по ланцюжку обробник.

У секції ініціалізації Init Виконується перевірка на наявність у пам'яті першого екземпляра резидента. Якщо перший екземпляр не виявлено, то незалежно від виду команди, що запускає програму ;(з опцією або без неї) відбувається перехід на мітку ОК з установкою програми в пам'яті. При виявленні першого екземпляра програми починається порівняння опції команди з очікуваною. Якщо результат порівняння виявився негативним (опція є але інша), програма завершується виведенням повідомлення про неможливість повторної установки. За ідентичності опції очікуваної резидент вивантажується з пам'яті з виведенням відповідного повідомлення.

Демонстрація роботи резидента ґрунтуєтьсяна показовому порівнянні “загальмованого” та “не загальмованого” системного часу. "Загальмований" системний час виходить в результаті роботи резидента. При цьому відбувається затримка часу на екран. "Не загальмований" час виводиться безпосередньо прикладним обробником 1Ch. Справа в тому, що будь-який коефіцієнт уповільнення не був встановлений, час у будь-якому випадку буде виводиться на екран, так як функція виведення системного часу встановлена ​​в алгоритмі уповільнення, суть якого полягає в багаторазовому виклику циклів (порядку кількох сотень тисяч разів за секунду). Таким чином можна порівняти реально час із загальмованим, а так само можна не озброєним оком визначити коефіцієнт уповільнення.

Весь інтерфейс демонстраційної програми оформлений у псевдографіці, має кілька інформаційних вікон – статус резидента, «гальмований час», «негальмований час», коефіцієнт уповільнення.

3. Результати демонстрації програми.

Під час запуску .com програми з командного рядка було виведено відповідне повідомлення про вдале завантаження резидента на згадку. Під час повторного запуску .com програми було виведено повідомлення, що резидент вже завантажено. Для подальшого продовження демонстрації роботи запустили демонстраційну програму зі спеціальним екранним інтерфейсом, де відображався стан резидента. У вікні Статус висвічується статус резидента, після попереднього включення режиму Scroll Lock послідовно тиснемо на цифрові клавіші, при цьому починає змінюватися інформація про стан резидента. Зауважимо, що за умовчанням резидент перебував у "прихованому" стані, що характеризувалося відсутністю системного часу, що виводиться на екрані, а також коефіцієнтом уповільнення 1. Варто зазначити, що змінакоефіцієнта уповільнення не відбувається миттєво, лише залежно від попереднього значення коефіцієнта уповільнення