Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises
Demon's Souls |#8| Maiden Astraea
Demon's Souls |#7| Dirty Colossus

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Стивенс Ал. Весь текст 495.21 Kb

Техника программирования на турбо-С

Предыдущая страница Следующая страница
1 ... 27 28 29 30 31 32 33  34 35 36 37 38 39 40 ... 43
крохотной модели памяти (64К на код, данные и стек), то вероятнее
всего она не должна быть резидентной.  Внушите себе это правило -
и это убережет вас от засорения памяти резидентными  утилитами за
счет  нужных  вам  обычных  программ.  Отметим,  что TSR-драйвер,
описанный в главе 12,  одинаково хорошо работает c программами  в
крохотной и малой моделях.

     - Частота  использования  утилиты.  Не  советуем  вам делать
резидентной программу расчета доходов.  Программы,  запускаемые с
частотой один раз в день должны быть нерезидентными, а один раз в
час  -  могут  стать   TSR.   Не   перегружайте   систему   редко
используемыми резидентными программами.

     - Ресурсы,   необходимые   утилите.  Если  программа  должна
запрашивать дополнительную память или ее характеристики снижаются
при ограничениях на память,  она не должна быть резидентной; ведь
она  может  быть  вызвана  во  время  выполнения   любой   другой
программы,  которая  может  занять  всю или большую часть памяти.
Если выполняется  COM-программа,  ДОС  считает,  что  занята  вся
память.

     - "Всплывающая" природа задачи.  Если программа используется
в дополнение к  другим  -  это  хороший  кандидат  в  резидентные
утилиты. Например, удобно, когда можно вызвать систему компоновки
текстов при работе с текстовым процессором. То же самое относится
к  программе-словарю.  Калькулятор  и  записная книжка необходимы
почти все время.  Синтаксический анализатор программ на Си  может
стать   полезной   TSR-программой  при  использовании  текстового
редактора для подготовки программ.  Но,  однако,  не нужно делать
все программы вызываемыми по нажатию клавиши.

     - Время,   нужное   для   выполнения.  Главное  преймущество
"всплывающих"  программ  -  это  их  немедленная  доступность   и
возможность выполнения без отрыва от основной работы, выполняемой
на компьютере. Если же утилита требует для выполнения целый день,
то нет смысла делать ее резидентной.

     (Люди привыкают   к   удобствам.  Еще  несколько  лет  назад
пользователи были довольны,  если ответ на запрос к  базе  данных
приходил  из  центральной  машины за ночь.  Сейчас же они ворчат,
если  им  надо  сохранить  данные  из   электронной   таблицы   и
возвратиться  в  ДОС,  чтобы  использовать программу для работы с
модемом.)



          ПОСТРОЕНИЕ TSR-ПРОГРАММ
-----------------------------------------------------------------

     При написании  резидентной  программы  вам  придется  решить
много   проблем.   Некоторые   из  них  незначительны,  некоторые
разрешаются при использовании  расширений  стандартных  библиотек
Турбо Си,  но некоторые являются крепким  орешком.  Использование
ассемблера для некоторых задач является более удобным,  но в этой
книге везде старались максимально использовать Си, где это только
предоставлялось возможным.

     Превращение программы в резидентную.
-----------------------------------------------------------------

     Чтобы стать  резидентной,  программа  должна  объявить  себя
соответствующим   образом.   Здесь   программисту   может  помочь
документация на ДОС.  О двух нужных для этого  функциях  ДОС  уже
было   упомянуто.   Чтобы  их  использовать,  надо  знать  размер
программы,  а для этого надо знать,  как она строится в Турбо Си.
Это в дальнейшем будет коротко объяснено. Если программа запущена
на выполнение,  присоединила себя к нужному вектору прерывания  и
сделала все,  что требуется для превращения в резидентную, то она
может  вызвать  одну  из  TSR-функций ДОС.  Действие этих функций
одинаково,  и можно использовать  функцию  0х31  прерывания  0х21
чтобы  объявить  программу  резидентной.  Далее  следует фрагмент
программы на Турбо Си, демонстрирующий эту возможность:

#include 
static struct REGS rg;
unsigned int sizeprogram;

rg.x.ax = 0x3100;
rg.x.dx = sizeprogram;
intdos(&rg,&rg);

     Переменная sizeprogram должна содержать размер  программы  в
шестнадцатибайтных параграфах.


     Резидентна ли уже программа?
-----------------------------------------------------------------

     Помните, что  ДОС  неизвестно,  что  ваша  программа   стала
резидентной  и каково ее имя (эта информация доступна,  но ДОС не
работает с  ней).  После  выполнения  TSR-программы несколько раз
несколько ее копий будет находиться в памяти,  поэтому  программе
надо проверять, не загружена ли уже ее копия. Простейшим способом
для организации такой  проверки  является  применение  одного  из
неиспользуемых   прерываний.   При  первом  старте  TSR-программа
выполняет это прерывание,  проверяя возвращаемое  значение.  Если
это  значение  не  равно  установленному  в  программе,  то можно
объявлять себя резидентной,  и программа присоединяется  к  этому
прерыванию.  После этого вызов этого прерывания будет приводить к
возврату  определенного  значения,  и  другие  копии  загруженной
программы после проверки не будут объявлять себя резидентными.

     Векторы 0х60-0х67 всегда доступны для использования, и можно
выбрать один из них.  Но нет уверенности,  что другая  программа,
взятая из другого источника,  не выберет тот же вектор.  Помните,
что ДОС ориентирована на одну выполняемую задачу,  и этой  задаче
дозволено использовать любое прерывание в системе.

     Более предпочтительным   является   использование    вектора
прерывания,  указывающего  на  сигнатуру  (уникальную  запись)  в
памяти программы.  Вместо запуска прерывания программа проверяет,
не указывает ли один из векторов 0х60-0х67 на эту сигнатуру. Если
таковой  указатель  существует,  то  в  памяти  уже  есть   копия
программы; если  же  такого не находится,  то программа объявляет
себя  резидентной  и  устанавливает  адрес  одного  из  свободных
прерываний на сигнатуру.  К несчастью, нет способов оградить этот
вектор от посягательтв другой программы.  Тут уж ни в чем  нельзя
быть уверенным.

     Чтобы найти неиспользуемый вектор прерывания, надо проверить
их все  на нулевое значение.  Вектор,  в который записан ноль,  и
есть неиспользуемый. В документации указано, что прерывания 0х60-
0х67 доступны для использования программами.

     Неиспользуемые векторы прерывания можно применять для других
видов связи  между  программами.  Некоторые  TSR-программы  можно
применять для задания параметров для своей же копии в памяти. При
выполнении таких программ  они  передают  новые  параметры  своим
копиям   через  вектор  прерывания.  Вектор  может  указывать  на
подпрограмму обработки прерывания в  TSR-программе;  а  сигнатура
находиться  с  определенным  смещением  с том же сегменте.  Найдя
сигнатуру,  вторая  копия  программы  может  взаимодействовать  с
первой  через  этот  вектор.  TSR-драйвер,  описанный в главе 12,
демонстрирует такой способ.


          Захват прерывания.
-----------------------------------------------------------------

     Вы можете  использовать прерывания не только для связи между
программами. По прерыванию может выполняться ваша программа, если
на  нее указывает соответствующий вектор.  В Турбо Си легко можно
выполнить подобный  захват прерывания.  С помощью функции setvect
можно оперативно выполнить эту задачу. Надо объявить функцию типа
interrupt,  которая будет обрабатывать прерывания,  и записать ее
адрес в нужный вектор.

Например:

setvect(vno,isr);

     Параметр vno - это int от 0  до  255,  а  isr  -  это  адрес
подпрограммы  обработки  прерывания,  которая  может быть описана
так:

void interrupt isr();

     Совместное использование прерываний.

     Если вы используете прерывания, нужные другим программам, то
надо  делать  это  так,  чтобы другие не замечали ваших действий.
Например,  если ваша  программа  присоединится  к  прерыванию  от
таймера  и  не позволит оставшейся части системы использовать это
прерывание, все процессы, работающие по таймеру, будут недоступны
все  то  время,  пока  ваша программа будет находиться в памяти и
удерживать  прерывание.  В  этом  случае,  например,  остановятся
системные часы.

     Вы можете присоединиться также к прерываниям  от клавиатуры,
прерываниям  для  вызова  функций  ДОС,  дисковых  функций BIOS и
другим прерываниям   поддержки  TSR-программ.  В  любом  из  этих
случаев  надо  совместно  использовать   прерывания   с   другими
процессами, нуждающимися в них.

     Возможность работать   с   прерыванием   другим   программам
выполняется следующим   образом.   Надо  прочитать  старый  адрес
прерывания, по которому передавалось управление до загрузки вашей
программы. В  библиотеке Турбо Си есть функция getvect для чтения
содержимого вектора прерывания. Надо объявить interrupt указатель
на функцию, и записать адрес из вектора в этот указатель:

void interrupt (*oldisr)();

oldisr = getvect(vno);

     Затем, запишите    адрес    вашей   подпрограммы   обработки
прерывания в вектор,  используя функцию setvect, описанную выше.

     В этой подпрограмме вы можете обеспечить  выполнение  старой
ISR,  после  предварительной  обработки  или  без  нее  передавая
управление по адресу старой ISR. Эти принципы обсуждаются в главе
12.



          Величина TSR-программы.
-----------------------------------------------------------------

     При объявлении программы резидентной надо специфицировать ее
размер,  чтобы ДОС было  известно,  сколько  памяти  отвести  для
нее. Для  безопасности можно отвести каждой программе по 64К,  но
при   этом   значительная   часть   занятой   памяти   может   не
использоваться. Легко определить размеры программы, написанной на
ассемблере,  но внутренняя структура программы на  Си  скрыта  от
программиста. Чтобы вычислить размер программы,  надо знать,  как
компилятор Турбо Си строит программу.

     Рисунок 11.3  демонстрирует  структуру  типичной программы в
крохотной модели памяти,  построенную Турбо Си.  Program  Segment
Prefix  (PSP)  - это конструкция ДОС,  помещаемая в начале каждой
программы. Она  будет  описана  позже.  Машинный  код   программы
следует сразу за PSP. Переменные,объявленные static или external,
и инициализированные при объявлении,  следуют за кодом, а за ними
идут неинициализированные   static   или   external   переменные.
Следующая  часть  программы   -   "куча",   область   динамически
распределяемой памяти.   Ее   размер  зависит  от  того,  сколько
программа будет распределять памяти.  Область стека располагается
за    "кучей",   и   его   размеры   увеличиваются   в   обратном
направлении. Первоначально  вершина  стека  указывает  на   конец
области в  64К,  занимаемой  программой  в крохотной модели.  При
использовании стека его указатель двигается в  сторону уменьшения
адресов. Величина  стека зависит от глубины вложенности функций и
количества локальных данных,  используемых в этих  функциях.  При
вызове  функции в стек помещаются параметры и значения регистров,
которые необходимо сохранить.  Если функция использует  локальные
automatic-переменные, они  тоже  запоминаются  в стеке.  Функция,
вызываемая   рекурсивно   и   использующая   большое   количество
параметров и  automatic-переменных,  будет  использовать  большую
часть стека.  Из-за динамической природы "кучи" и стека вы можете
только делать некоторые предположения о размерах программы.

 ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД¬
 ¦                                                      ¦
 ¦                        СТЕК                          ¦
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦                      " КУЧА "                        ¦
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦    НЕИНИЦИАЛИЗИРОВАННЫЕ STATIC И EXTERNAL ДАННЫЕ     ¦  BSS
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ<ДДДДДД
 ¦                                                      ¦
Предыдущая страница Следующая страница
1 ... 27 28 29 30 31 32 33  34 35 36 37 38 39 40 ... 43
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама