Главная · Поиск книг · Поступления книг · 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 ... 28 29 30 31 32 33 34  35 36 37 38 39 40 41 ... 43
 ¦     ИНИЦИАЛИЗИРОВАННЫЕ STATIC И EXTERNAL ДАННЫЕ      ¦  DATA
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ<ДДДДДД
 ¦                                                      ¦
 ¦                                                      ¦
 ¦                   КОД ПРОГРАММЫ                      ¦
 ¦                                                      ¦  TEXT
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ<ДДДДДД
 ¦                                                      ¦
 ¦                      P S P                           ¦
 АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

рис.11.3. Структура программ с крохотной моделью памяти
          в Турбо Си.

     Приблизительно подсчитать размер программы  можно, используя
MAP-файл,  генерируемый программой TLINK.  В его начале находится
информация, подобная следующей:

     Start  Stop   Length Name                Class

     00000H 010BAH 010BBH _TEXT               CODE
     010C0H 013D8H 00319H _DATA               DATA
     013DAH 013DDH 00004H _EMUSEG             DATA
     013DEH 013DFH 00002H _CVTSEG             DATA
     013E0H 013E5H 00006H _SCNSEG             DATA
     013E6H 014EDH 00108H _BSS                BSS
     014EEH 014EEH 00000H _BSSEND             BSSEND

     Самая правая колонка,  с заголовком  class,  показывает  тип
сегментов,  представленных  значениями  в  левых  колонках.  CODE
содержит код   программы,   DATA   содержит    инициализированные
переменные, а BSS - неинициализированные. Значение в колонке Stop
равно      шестнадцатиричному      адресу      конца      области
неинициализированных переменных  и начала "кучи".  Программа,  не
использующая стека и "кучи",  будет иметь  размер,  равный  этому
значению + 256 байт на PSP.

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

     Лучший метод  найти  оптимальный размер стека - метод проб и
ошибок. Сначала запустите программу  на  64К,  а  затем  смещайте
вершину стека  к  меньшим адресам.  При каждом таком передвижении
испытывайте  программу  в  условиях  максимального  использования
стека и  "кучи".  Продолжайте эксперименты до тех пор,  пока ваша
программа   не   будет   "вешать"   систему    или    неправильно
выполняться. Затем поставьте вершину стека на безопасное смещение
и интенсивно используйте программу, пока не поверите наконец, что
стек безопасен для "кучи".

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



          Переключение контекстов.
-----------------------------------------------------------------

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


          Стек.
-----------------------------------------------------------------

     Для всех программ нужен стек.  У резидентной программы  есть
свой  стек,  но после прерывания текущей задачи указатель стека и
сегмент  стека  в  компьютере  указывают   на   стек   прерванной
задачи. Может  показаться,  что лучшее решение - это использовать
стек прерванной   программы.   На   деле   многие    ассемблерные
TSR-программы так и делают,  но для этого приходится ограничивать
использование стека.  Но,  во-первых,  неизвестно,  какой  размер
стека был  у прерванной программы.  А во-вторых,  ДОС гарантирует
достаточный размер стека только для сохранения  регистров.  Си  -
язык с   интенсивным  использованием  стека,  и  вам  понадобится
больший его размер,  чем обеспечивает ДОС, и это значит, что надо
переключаться на собственный стек.

     Переключение на   собственный   стек   означает,   что  надо
запомнить значение региста сегмента стека до переключения.  И это
значение  должно  быть  восстановлено  до  передачи  управления в
прерванную программу.  Регистры сегментов и указателей могут быть
прямо адресованы в Турбо Си использованием псевдопеременных _SS и
_SP. При   объявлении   резидентной   TSR-программа    запоминает
собственный сегмент  стека.  После вызова она запоминает контекст
стека прерванной  программы  и  устанавливает  свой   стек.   Это
производится  с  помощью  установки  регистра  сегмента  стека на
значение,  запомненное при первом запуске,  и указателя стека  на
величину, вычисленную из размеров программы.

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

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


     Program Segment Prefix (PSP).
-----------------------------------------------------------------

     PSP - это управляющая область в 256 байт, которая строится в
памяти в начале каждой программы.  Она содержит  различные  поля,
используемые ДОС  для  управления выполнением программы.  На рис.
11.4 показана ее структура. Далее будут обсуждаться все поля PSP.
Заметим,  что  многие эти поля не были официально описаны фирмами
Microsoft или IBM.  Они используются так, как описано ниже, но их
использование    или   модификация   в   прикладной   задаче   не
санкционировано при продаже.  Знание  этих  полей  -  подарок  от
хэккеров, расчленивших  ДОС и напечатавших о своих находках.  Эти
данные верны для популярных версий ДОС - 2.0, 2.1, 3.0, 3.1, 3.2,
3.3,  за  исключением специально оговоренных случаев.  ДОС 4.0 не
публиковалась в США,  и,  как утверждается,  будущие  версии  ДОС
будут  поддерживать мультизадачность и будут предназначены только
для компьютеров с процессорами 80286/80386.  Использование  полей
PSP описанным  способом  совершенно безопасно.  Многие популярные
коммерческие программы делают это точно так же.
 ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД¬
 ¦                                                      ¦
 ¦      Вызов прерывания для завершения процесса        ¦ 0000
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦       Сегментный адрес верхней границы памяти        ¦ 0002
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦                          0                           ¦ 0004
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦      Команда вызова диспетчера функций ДОС           ¦ 0005
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦             Адрес обработчика завершения             ¦ 000A
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦             Адрес обработчика Ctrl-Break             ¦ 000E
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦         Адрес обработчика критических ошибок         ¦ 0012
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦             Сегментный адрес PSP родителя            ¦ 0016
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦              Таблица указателей файлов               ¦ 0018
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦     Сегментный адрес области системных параметров    ¦ 002C
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦        Адрес стека на время вызова функции ДОС       ¦ 002E
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦           Размеры таблицы указателей файлов          ¦ 0032
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦           Адрес таблицы указателей файлов            ¦ 0034
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦                Зарезервировано ДОС                   ¦ 0038
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦               Блок управления файлом #1              ¦ 005C
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦               Блок управления файлом #2              ¦ 006C
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 ¦                                                      ¦
 ¦        Остаток командной строки/Дисковый буфер       ¦ 0080
 АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                 рис.11.3. Структура PSP.

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

Реклама