Асемблер (асемблер)
Асемблер (монтажник). Разработка на резидентни манипулатори
Разработете постоянен модератор за изпълнение на програми. Забавянето се изпълнява от програма за забавяне, вмъкната в манипулатора на потребителските прекъсвания на таймера (int 1Ch). Инициализирането на резидента се извършва чрез комбинация от ключове. Стойността на символа на цифровия ключ влияе върху скоростта на забавяне.
2. Структура и описание на разработката
Цялата разработка се състои от два файла: *.com - самият резидент и *.exe - демо програмата. Нека първо разгледаме структурата и принципа на работа на резидента. Файлът *.com съдържа следните манипулатори: потребителски манипулатор new_1Ch, който замества прекъсването 1Сh, потребителски манипулатор на клавиатурата new_09h, който замества системния манипулатор 09h, и манипулатор new_2Fh, който замества съответното прекъсване. Файлът съдържа и допълнителни полета и методи, необходими за коректното функциониране на резидента.
Нека разгледаме работата на манипулатора на прекъсване на персонализираното приложение new_1Ch, който замества манипулатора на приложеното хардуерно прекъсване на DOS Int 1Ch, който е част от системния манипулатор на BIOS 08h, за продължителността на резидента. Новият манипулатор съдържа алгоритъм за забавяне на изпълнението на програми въз основа на факта, че прекъсването на 1Ch се извиква приблизително 18 пъти в секунда. Оказва се, че всяко обаждане се случва приблизително на всеки 55 ms. По този начин, за да се забави изпълнението на програмите, е възможно да се пропусне всяко n-то повикване и да се забави останалите със специален алгоритъм. Получаваме забавител за n пъти изпълнението на програмите, където n е коефициентът на забавяне,който се управлява от променливата cnt, която е в кодовия сегмент. Тази променлива може да приема стойности от 0 до 8. Трябва да се добави, че манипулаторът new_1Ch има още една функция - демонстрационна. Показва незабавено системно време. Това означава, че без значение в какъв режим на забавяне е манипулаторът, системното време ще се показва на екрана. Нека сега разгледаме работата на алгоритъма за забавяне. При следващото извикване на манипулатора new_1Ch се проверява режимът на работа на ускорителя. Режимът на работа се характеризира със състоянието на променливата fn, разположена в кодовия сегмент. Тази променлива може да приема стойности от 0 до 8. Стойността на променливата „0“ съответства на „скрит“ режим на работа, при който системното време не се показва на екрана и не се появява забавяне. Променливите стойности от 1 до 8 характеризират съответния коефициент на забавяне за показаното системно време. Така че, когато задавате резидентния режим на работа (по подразбиране е 0), коефициентът на забавяне се задава на променливата cnt, съхранена там, и също така се определя от режима на работа дали да се показва или не системното време на екрана. Коефициентът на забавяне е броят на извикванията на процедурата за забавяне на изпълнението на програмата, чието време за изпълнение е приблизително равно на 55 ms. След това променливата f1 се анализира за това какво прави този път: преминаване към Iret или забавяне на изпълнението. Ако fn==0, тогава отиваме на изхода и задаваме fn=1, ако fn==1, тогава стартираме алгоритъма за забавяне с възможност за показване на системния такъв или без него. След завършване на алгоритъма fn се задава на 0, т.е. следващия път, когато манипулаторът бъде извикан, няма да има забавяне.
Заслужава да се отбележи, че променливата fn, която характеризира режима на работа на резидентаразположен дори в кодовия сегмент, но не в рамките на функцията new_1Ch, а извън нея. Това е необходимо за публичната достъпност на тази променлива, т.к той се използва от персонализирания манипулатор new_09h за задаване на режима на работа, както и манипулаторът new_2Fh за четене.
Мултиплексното прекъсване new_2Fh работи на следния принцип: първо се проверява съдържанието на регистъра ax за заявка за резидентен режим на работа, ако възникне такава заявка, след това се връща съдържанието на променливата fn в същия регистър и процедурата излиза. Ако такава заявка не е получена, тогава същият регистър се анализира за наличието на нашата функция в паметта. Струва си да се отбележи, че идентификаторът 0C88h е присвоен на функцията. Ако има резидент в паметта, стойността 0ffh ще бъде върната в ниския байт на регистъра ax. Ако тази заявка не бъде получена, тогава се проверява наличието на заявка за деинсталиране. Ако резултатът е положителен, всички прихванати преди това вектори се възстановяват и разтоварват от резидентната памет заедно с PSP. При липса на всички горепосочени заявки ще има преход към следващия манипулатор във веригата.
В раздела за инициализация Init Проверява за наличието на първото копие на резидента в паметта. Ако първият екземпляр не бъде намерен, тогава независимо от типа на командата, която стартира програмата; (със или без опцията), преходът към етикета OK става с инсталирането на програмата в паметта. Когато бъде намерено първото копие на програмата, започва сравнението на командата с очакваната. Ако резултатът от сравнението се окаже отрицателен (опцията е там, но е различна), програмата завършва със съобщение за невъзможността за преинсталиране. Ако опцията е идентична с очакваната, резидентът се разтоварва от паметта с извеждане на съответното съобщение.
Базира се демонстрация на работата на резидентпри индикативно сравнение на "инхибирано" и "неинхибирано" системно време. „Мудото“ системно време е резултат от работата на резидента. Това причинява забавяне на показването на времето на екрана. Времето без спирачки се извежда директно от манипулатора на приложения 1Ch. Факт е, че не е зададен коефициент на забавяне, времето така или иначе ще бъде показано, тъй като функцията за извеждане на системното време е зададена в алгоритъма за забавяне, чиято същност е многократно извикване на цикли (от порядъка на няколко стотици хиляди пъти в секунда). По този начин е възможно да се сравни действителното време на работа с инхибираното, а също така е възможно да се определи коефициентът на забавяне с просто око.
Целият интерфейс на демонстрационната програма е проектиран в псевдографика, има няколко информационни прозореца - статус на резидент, "забранено време", "незабранено време", коефициент на забавяне.
3. Резултати от демонстрацията на програмата.
Когато програмата .com беше стартирана от командния ред, се появи съответното съобщение за успешното зареждане на резидента в паметта. При рестартиране на .com приложението се изписваше съобщение, че резидентът вече е зареден. За по-нататъшно продължаване на демонстрацията на работа беше стартирана демонстрационна програма със специален екранен интерфейс, който показваше състоянието на резидента. В прозореца на състоянието се показва състоянието на резидента, след като първо включите режима Scroll Lock, последователно натискаме цифровите клавиши и информацията за състоянието на резидента започва да се променя. Обърнете внимание, че по подразбиране резидентът беше в „скрито“ състояние, което се характеризираше с липсата на показано системно време на екрана, както и коефициент на забавяне от 1. Заслужава да се отбележи, че промянатакоефициентът на забавяне не се появява моментално, а само в зависимост от предишната стойност на коефициента на забавяне