- •1. Основы программирования для dos 9
- •1.1.7. Средства bios 21
- •2. Приемы системного программирования 57
- •Введение
- •1.Основы программирования для dos
- •1.1. Структура и выполнение программ в dos
- •Программа типа сом
- •Программа типа ехе
- •1.2.Использование служебных функций dos и bios
- •1.3.Вывод на экран в текстовом режиме
- •Средства dos
- •Средства bios
- •Выбор видеорежима
- •Управление положением курсора
- •Вывод символов на экран
- •Прямая работа с видеопамятью
- •1.4.Ввод с клавиатуры
- •Средства dos
- •Средства bios
- •1.5.Графические видеорежимы
- •Работа со стандартными графическими режимами
- •Работа с svga-режимами
- •(Продолжение таблицы 4)
- •(Окончание таблицы 4)
- •1.6.Работа с мышью
- •1.7.Другие устройства
- •Системный таймер
- •Последовательный порт
- •Параллельный порт
- •1.8.Работа с файлами
- •Создание и открытие файлов
- •Чтение из файла и запись в файл
- •Закрытие и удаление файла
- •Поиск файлов
- •Управление файловой системой
- •1.9.Управление памятью
- •Обычная память
- •Область памяти umв
- •Область памяти нма
- •Интерфейс ems
- •Интерфейс xms
- •1.10.Организация процессов
- •Запуск программ на выполнение
- •Переменные окружения
- •Командные параметры
- •2.Приемы системного программирования
- •2.1.Управляющие структуры
- •Структуры if... Then... Else
- •Структуры case
- •Конечные автоматы
- •2.2.Процедуры и функции
- •Передача параметров
- •Передача параметров по значению
- •Передача параметров по ссылке
- •Передача параметров по возвращаемому значению
- •Передача параметров по результату
- •Передача параметров по имени
- •Передача параметров отложенным вычислением
- •Передача параметров в регистрах
- •Передача параметров в глобальных переменных
- •Передача параметров в стеке
- •Передача параметров в потоке кода
- •Передача параметров в блоке параметров
- •Локальные переменные
- •2.3.Обработка прерываний
- •Обработчики прерываний
- •Прерывания от внешних устройств
- •Взаимодействие прикладных и системных обработчиков прерываний
- •2.4.Резидентные программы
- •Системные средства организации резидентных программ
- •Взаимодействие с резидентной программой
- •2.5.Драйверы устройств в dos
- •Литература
Взаимодействие с резидентной программой
Для обращения к резидентной программе из транзитной можно использовать область межзадачных связей, являющуюся частью области данных BIOS и расположенную по адресам 0040h:[00F0h...00FFh]. Эта область не используется системой и предназначена специально для коммуникации программ пользователя. С помощью области межзадачных связей можно осуществлять как вызов резидентной программы, так и передачу параметров, причем удобнее передавать не сами параметы, а их адреса (передача по ссылке).
Другой метод передачи резидентной программе управления и параметров заключается в использовании свободных векторов, например, 60h - 66h.
Для взаимодействия с параллельными процессами и, в частности, с резидентными программами в DOS предусмотрен стандартный интерфейс — мультиплексорное прерывание 2Fh.
INT 2Fh — Мультиплексорное прерывание
Ввод: AH = идентификатор программы
00h – 7Fh зарезервировано для DOS/Windows
B8h – BFh зарезервировано для сетевых функций
C0h – FFh отводится для программ
AL = код функции
00h — проверка наличия программы
остальные функции — свои для каждой программы
BX, CX, DX = 0 (так как некоторые программы выполняют те или иные действия в зависимости от значений этих регистров)
Вывод: AL = состояние резидентной программы, если на входе AL = 00h:
0 — программа не установлена;
1 — программа не установлена и ее установить нельзя;
0FFh и какой-либо идентифицирующий код в других регистрах, если программа установлена;
CF = 1, AX = код ошибки, если возникла ошибка.
Это прерывание используется прежде всего с целью исключения повторной установки уже загруженной в память программы. Чтобы резидентная программа отзывалась на прерывание 2Fh, в нее следует включить обработчик одной или нескольких функций этого прерывания.
Проверка на повторную установку является одним из примеров связи с резидентной программой. В случае отсутствия такой проверки новые экземпляры программы могут логически "деактивировать" предыдущие, но могут и сцепляться с ними, что при передаче управления резидентной программе приведет к последовательному выполнению всех ее копий. В любом случае каждая новая копия программы уменьшает размер свободной памяти (обычной).
Кроме описанного способа защиты резидентной программы от повторной загрузки при помощи мультиплексорного прерывания иногда применяется способ с использованием сигнатуры (некоторого произвольного кода) в загрузочном модуле программы. Прежде чем выполнить установку резидентной части, инициализационная секция проверяет наличие сигнатуры и в случае ее присутствия аварийно завершается. Эта методика, однако, не помогает, если после инициализации и установки такой программы загружается резидентная программа обработки того же прерывания, поскольку в ней, разумеется, данная сигнатура отсутствует.
Еще одной задачей, связанной с разработкой резидентных программ, является задача выгрузки из памяти. Для этого необходимо сделать три действия: закрыть открытые программой файлы и устройства, восстановить все перехваченные векторы прерываний и, наконец, освободить всю занятую программой память. Трудность может вызвать второй шаг, так как после нашего резидента могли быть загружены другие программы, перехватившие те же прерывания. Если в такой ситуации восстановить вектор прерывания в значение, которое он имел до загрузки нашего резидента, программы, загруженные позже, не будут получать управление. Более того, они не будут получать управление только по тем прерываниям, которые у них совпали с прерываниями, перехваченными нашей программой, в то время как другие векторы прерываний будут все еще указывать на их обработчики, что почти наверняка приведет к ошибкам. Поэтому, если хоть один вектор прерывания не указывает на наш обработчик, выгружать резидентную программу нельзя.
Последний шаг в выгрузке программы — освобождение памяти — можно выполнить вручную, вызывая функцию DOS 49h для каждого блока памяти, который программа выделяла с помощью функции 48h, для блока с окружением DOS, если он не освобождался при загрузке, и наконец, для самой программы. Однако есть способ заставить DOS сделать все это (а также закрыть открытые файлы и вернуть код возврата) автоматически, объявив резидент текущим процессом и вызвав функцию 4Ch (Exit).