Системное программное обеспечение персональных ЭВМ

         

Переключение контекста


15.4. Переключение контекста

Под контекстом мы понимаем все системные переменные, указатели и т.п., значения которых определяют выполняемую (активную) в данный момент программу. Фактически контекст содержит описание ресурсов, выделенных данной программе, так как в его составе - стек программы, таблица файлов задачи, дисковая передаточная область.

При инициализации функция main обращается к функции get_context, которая запоминает переменные контекста.

Запоминается содержимое стековых регистров программы (содержимое регистра SP запоминается с уменьшением на 200, так как часть стека используется при инициализации TSR-программы; в случае, если размер оставляемой в памяти части TSR-программы уменьшается, следует перевычислить значение SP в соответствии с устанавливаемым размером). Если TSR-программа не будет при активизации переключаться на свой стек, она будет использовать стек фоновой программы; даже при аккуратной работе с этим стеком (TSR-программа не должна в нем ничего "забывать" или наоборот - выбирать лишнее) это может привести к аварии, если размер стека фоновой программы будет невелик.

Запоминается адрес дисковой передаточной области, назначенной программе. Это, как правило, не обязательно и необходимо только в том случае, если TSR-программа использует функции, работающие с DTA.

Запоминается адрес PSP программы. Не все TSR-программы это делают, но это совершенно необходимо, если TSR-программа использует функции файлового ввода-вывода метода дескрипторов DOS. Поскольку PSP содержит ссылку на таблицу файлов задания, переключение на свой PSP дает TSR-программе возможность работать с собственной таблицей файлов. Использование таблицы файлов фоновой программы в большинстве случаев рисковано, и оно совершенно невозможно в тех случаях, когда TSR -программе необходимо сохранять свои файлы открытыми между свими активизациями.

Когда выполнены условия активизации TSR-программы, происходит обращение к функции act_tsr. Эта функция устанавливает флаг активности tsr_run и обеспечивает переключение контекста с фоновой программы на TSR-программу.
В операции по переключению контекста входят: сохранение значений регистров SS, SP, указывающих на стек фоновой программы, и установка собственных значений этих регистров, запомненных в get_context (на время изменения значений в стековых регистрах запрещаются прерывания); перехват вектора прерывания 0x24 - обработки критических ситуаций (прежний вектор сохраняется); получение и сохранение статуса обработки Ctrl+Break, установленного в фоновой программе, и отключение этой обработки (можно также перехватывать вектор прерывания 0x23, устанавливая собственный обработчик Ctrl+Break); сохранение адреса DTA фоновой программы и установка адреса своей DTA; запоминание PID текущей программы и установка собственного PID (с этого момента система "знает", что активной стала наша программа).

После переключения контекстов вызывается функция tsr_exec, выполняющая "прикладные" действия - то, для чего и разрабатывалась TSR-программа. После выполнения прикладной части происходит обратное переключение контекстов - восстановление запомненных адресов, переменных и т.д. фоновой программы, заканчивается функция act_tsr сбросом флага активности TSR-программы.

Прикладная часть нашей TSR-программы (функция tsr_exec) имеет только демонстрационное назначение: она выводит в левый верхний угол экрана сообщение о работе TSR-программы, которое снимается по нажатию любой клавиши. Однако, даже в такой простой функции следует обратить внимание на два важ- ных момента. Во-первых, переключение контекстов как бы продолжается в прикладной части. Мы имеем в виду сохранение образа той части экрана, которая будет перекрыта сообщением TSR-программы и восстановление этого образа перед возвратом из функции. В более общем случае следует, возможно, сохранять и восстанавливать и номер видеорежима, позицию курсора, номер текущей видеостраницы и т.д. Во-вторых, обратите внимание на то, что для вывода информации мы используем здесь прямую запись в видеопамять, а для ввода (ожидание нажатия клавиши) - прерывание BIOS.Это неслучайно: ведь по условиям применения прерывания 0x28 нам запрещено использование функций консольного ввода-вывода DOS.

Содержание раздела