ISR таймера и DOSOK. Если производится дисковая операция, то TSR
не разрешает прерывание.
Прерывание тяжелой ошибки в ДОС.(0х24)
При возникновении тяжелой ошибки ДОС вызывает прерывание
0х24. Например, при обращении к дискете в открытом дисководе, ДОС
обнаруживает состояние неготовности и вызывает прерывание тяжелой
ошибки. Если программа не присоедиила себя к вектору 0х24, все
критические ошибки будут обрабатываться ISR в командном
процессоре ДОС. Он выдает сообщение "Abort,Retry, or Ignore" на
экран. ISR возвращает в ДОС значение, определяющее порядок
дальнейшей обработки.
Предположим, что ни одна программа не присоединена к вектору
0х24. Ваша TSR прерывает нерезидентную программу, и пытается
прочитать дискету из открытого дисковода. Командный процессор ДОС
перехватывает управленеие и запрашивает пользователя о дальнейших
действиях. Пользователь отвечает "A" (Abort-прервать), и ДОС
пытается прервать выполнение программы. Если ваша TSR переключила
адрес PSP, то ДОС будет пытаться прервать TSR. ДОС не знает, что
в памяти находится нерезидентная программа в прерванном
состоянии, и не возвращает ей управление. Система ломается. Если
TSR не переключала PSP, то ДОС завершает нерезидентную программу
и не возвращает управление TSR.
Предположим, что нерезидентная программа присоединилась к
вектору 0х24. Дисковая ошибка в вашей программе вызовет
исполнение обработчика тяжелой ошибки из прерванной нерезидентной
программы.
TSR должна присоединяться к вектору 0х24 в любом случае,
будет ли или не будет в ней какая-либо обработка ошибок. Вектор
присоединяется при "всплытии" TSR и восстанавливается на тот, что
был, при возвращении управления в прерванную программу. Никакие
обстоятельства не должны заставить TSR просить ДОС прервать
обработку. Большинство TSR-программ просто игнорируют ошибки и
говорят ДОС также их игнорировать. Прерывание тяжелой ошибки не
связывается в цепочки - это опасно. Если другая TSR-программа
(например, спулер) присоединила к себе вектор 0х24 и вызвана
после вашей TSR, она получит ваши ошибки. Если же эта программа
была вызвана до вашей TSR, то вы будете получать ее ошибки и
говорить ДОС игнорировать их, что является проблемой, которую
нельзя разрешить без написания системно-ориентированного
обработчика ошибок.
Прерывание Ctrl-Break в ДОС.(0х23)
-----------------------------------------------------------------
При нажатии пользователем клавиш Ctrl-Break ДОС отображает
на экране в текущей позиции курсора символы ^C и вызывает
прерывание 0х23. Обработчик этого прерывания, имеющийся в ДОС,
вызывает немедленное завершение текущей программы. TSR-программу
завершать таким способом нельзя: слишком много векторов
прерываний прикреплено к ней, и нерезидентная программа может
находиться в памяти за ней. Если вы просто проигнорируете это
прерывание, имеется риск, что другая программа, загруженная за
вашей, присоединит себя к этому прерыванию и сделает что-то
неподходящее при нажатии клавиш Ctrl-Break во время выполнения
вашей программы.
В ДОС имеется функция (0х33), которая позволяет программе
читать текущий статус (разрешено/запрещено) обработки Ctrl-Break
и устанавливать его. При вызове TSR-программы она должна
прочитать текущее значение статуса, и затем запретить обработку
Ctrl-Break. При завершении своей работы TSR должна восстановить
значение статуса обработки Ctrl-Break. Присоединяться к этому
прерыванию нет необходимости.
После таких действий вашей TSR в случае нажатии Ctrl-Break
во время ее выполнения, после возврата в прерванную программу она
будет закончена ДОС. Если все TSR будут использовать такой
способ, то завершаться по Ctrl-Break будут только нерезидентные
программы.
Выполнение TSR-программы.
-----------------------------------------------------------------
Выполнение TSR-программы проходит в два этапа. Первый этап -
когда пользователь запускает ее из командной строки. Программа
выполняет инициализационный код, сохраняет свой контекст,
присоединяет себя к прерываниям, если это нужно, и завершается с
использованием функции ДОС TSR, таким образом объявляя себя
резидентной.
Второй этап - когда TSR-программа запускается в результате
одного из прерываний, к которому она прикрепилась. В большинстве
случаев, векторы прерываний связываются в цепочки, как это было
описано ранее. Программа определяет, может ли она выполняться -
это зависит от состояния некоторых важных системных индикаторов,
описанных выше. Если она может выполняться, она сохраняет
контекст прерванной программы, восстанавливает свой собственный
контекст, выполняет свою задачу, восстанавливает контекст
прерванной программы, и передает ей управление.
Завершение TSR-программы.
-----------------------------------------------------------------
Могут быть причины, по которым вы можете захотеть завершить
TSR-программу, что отнюдь не является легкой задачей. Вспомните,
ведь ДОС не знает ничего о программе, оставшейся резидентной, и
вам самим надо сделать все то, что обычно делает ДОС по отношению
к обычным нерезидентным программам.
Завершение TSR-программы включает в себя следующие шаги:
1. Сообщение программе о том, что ей надо завершиться.
Для этого можно использовать другой "горячий ключ", или
коммуникационный вектор прерывания, указывающий на сигнатуру в
программе, означающую, что программа уже в памяти. Второй метод
используется в драйвере TSR-программ, описанном в главе 12. При
этом пользователь, знающий, что программа уже резидентна,
запускает ее второй раз, давая в командной строке параметр,
означающий, что программа должна завершиться. Программа ищет свою
сигнатуру способом, описанным выше. При нахождении сигнатуры она
также находит свой вектор прерывания. Через этот вектор она
посылает команду завершения свой резидентной копии, после чего та
совершает следующие шаги завершения.
2. Восстановление векторов прерывания в первоначальное
состояние.
У вас может быть возможность сделать это, а может и не быть.
Если другая TSR-программа была загружена после вашей, и она
связала векторы в цепочки, то вы успешно дезактивируете ее при
восстановлении векторов. Далее, если эта TSR-программа будет
затем завершена, то она переустановит вектора на адреса в вашей
программе, по которым уже может находиться неизвестно что. Так
что до того, как восстанавливать вектора, надо убедиться, что
ваша программа до сих пор владеет ими. Чтобы определить это, надо
сравнить адреса, находящиеся в соответствующих векторах, с
адресами соответствующих обработчиков в вашей программе. Если
какой-либо вектор изменен, то ваша программа уже не владеет им,
поэтому завершать ее нельза и надо просто приостановить ее.
Еще одним осложнением, возникающем при завершении вашей TSR
с другой программой такого же типа, загруженной после нее,
является фрагментация памяти в нерезидентной области. ДОС будет
использовать область, освобожденную вашей программой, при
запросах на память из выполняющихся программ, но для загрузки
других программ эта область не будет использоваться. Помните, что
ДОС - однозадачная ОС - не понимает концепции фрагментированных
программ, потому что она не понимает мультипрограммирование.
3.Закрытие всех файлов, открытых в программе.
При завершении нерезидентной программы ДОС автоматически
закрывает все файлы, сканируя массив указателей файлов программы
в PSP и закрывая все вхождения в него, которые еще
используются. Помните, что эти вхождения - это номера элементов
массива, который поддерживает ДОС. При завершении и объявлении
резидентной ДОС не закрывает файлы, открытые этой программой, и
при завершении работы TSR-программы необходимо это сделать. Если
файлы не будут закрыты, то элементы массива не будут освобождены,
и будут недоступны для дальнейшего использования другими
программами. Загрузка и завершение без закрытия файлов
TSR-программ может привести к исчерпанию таблицы файлов ДОС и
"зависанию" системы.
Элементы в таблице указателей файлов представляют файлы на
уровне указателей. Это эквивалентно функциям небуферизованного
ввода-вывода низкого уровня в Си. Функции Си, выполняющие
буферизованный потоковый ввод-вывод, поддерживают собственные
буферы и указатели и могут потребовать особого порядка
закрытия, называемого потоковым. Такое закрытие - это
библиотечная функция Си, отличающаяся от соответствующей функции
ДОС. Такие файлы надо закрывать стандартной функцией fclose.
Файлы, открытые функциями open и creat, могут быть закрыты
функцией close.
4.Возврат памяти, занимаемой программой, в ДОС.
Для этого можно использовать функцию ДОС 0х49.
TSR-программой, как минимум, занимается два блока памяти. Первый
- это блок системных параметров, адрес которого хранится в PSP со
смещением 0х2с. Второй блок - это сам PSP. Если программе
выделены оба этих блока, то они оба должны быть возвращены ДОС. В
главе 12 демонстрируется техника сканирования списка управляющих
блоков памяти ДОС для нахождения и возвращения в ДОС блоков
памяти, выделенных программе.
Приостановка и возобновление выполнения TSR-программы.
-----------------------------------------------------------------
При приостановке TSR-программы ее не удаляют из памяти, а
только дают ей команду не реагировать на прерывания путем
установки флага. Команда возобновления сбрасывает этот флаг. С
этой целью можно использовать коммуникационный вектор прерывания.
TSR-драйвер в главе 12 использует эту технику для
завершения, приостановки, и возобновления выполнения
TSR-программ.
Выводы.
-----------------------------------------------------------------
В этой главе описывается операционное окружение резидентных
программ. В главе 12 на примере двух таких программ описывается
весь процесс шаг за шагом. Первая программа - это оперативная
программа-часы, которая поддерживает на экране постоянное
отображения текущих времени и даты. Вторая программа более
интересна - это TSR-драйвер. Вы связываете свою программу на
Турбо Си c этим драйвером, используя некоторые соглашения для
инициализации, и ваша программа на Турбо Си становится
резидентной. Это значит, что программа будет вызываться по
нажатию клавиши, что она может открывать, читать, пиать в и
закрывать дисковые файлы, что она использует ROM-BIOS функции для
чтения с клавиатуры и прямой доступ к видеопамяти для вывода на
экран, и что она никогда не выходит в ДОС.
ГЛАВА 12
Построение резидентных программ
-----------------------------------------------------------------
В этой главе демонстрируется, как концепции TSR-программ,
описанные в главе 11, воплощаются на практике в программы на
Турбо Си. Функции из этой главы представляют собой
программу-драйвер, связав которую с вашей программой на Турбо Си,
вы получите резидентную программу. Имеются некоторые ограничения
на эту программу. Первое - это то, что в ней не должны
применяться функции Турбо Си, вызывающие прерывание ДОС 0х21 с
номерами функций от 0 до 12. Это означает, что весь обмен с
клавиатурой и экраном должен выполняться с помощью вызовов BIOS
или прямого доступа к экранной памяти. В примерах используются