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

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


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

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


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

Справочник программиста на IBM PC

Предыдущая страница Следующая страница
1 ... 3 4 5 6 7 8 9  10 11 12 13 14 15 16 ... 92
точке).  Для COM файлов FINISH дает смещение от начала PSP, как и
требуется для прерывания  27H.  Для  EXE файлов смещение отсчиты-
вается  от первого байта, следующего за PSP, поэтому к нему необ-
ходимо прибавить 100H, чтобы пересчитать  на начало PSP. Заметим,
что  поместив  процедуру в начало программы, мы  можем  исключить
установочную часть кода из  резидентной  порции. Другой возможный
фокус состоит в использовании инструкции MOVSB для пересылки кода
процедуры вниз в  неиспользуемую  часть  PSP, начиная со смещения
60H, что освобождает 160 байт памяти.
   Случай файла COM:
;---здесь процедура прерывания
BEGIN:     JMP   SHORT SET_UP  ;переход на установку
ROUTINE    PROC  FAR
           PUSH  DS            ;сохранение регистров
            .
      (процедура)
            .
           POP   DS            ;восстановление регистров
           IRET                ;возврат из прерывания
FINISH     EQU   $             ;отметка конца процедуры
ROUTINE    ENDP

;---установка вектора прерывания
SET_UP:    MOV   DX,OFFSET ROUTINE  ;смещение процедуры в DX
           MOV   AL,70H             ;номер вектора прерывания
           MOV   AH,25H             ;функция установки вектора
           INT   21H                ;устанавливаем вектор
;---завершение программы, оставляя резидентной
           LEA   DX,FINISH          ;определяем треб. смещение
           INT   27H                ;завершение

   Случай файла EXE:

;---здесь резидентная процедура
           JMP   SHORT SET_UP   ;переход на установку
ROUTINE    PROC  FAR
           PUSH  DS             ;сохранение регистров
            .
       (процедура)
            .
           POP   DS             ;восстановление регистров
           IRET                 ;возврат из прерывания
FINISH     EQU   $              ;отметка конца процедуры
ROUTINE    ENDP

;---установка вектора прерывания
SET_UP:    MOV   DX,OFFSET ROUTINE  ;смещение процедуры в DX
           MOV   AX,SEG ROUTINE     ;сегмент процедуры в DS
           MOV   DS,AX              ;
           MOV   AL,70H             ;номер вектора прерывания
           MOV   AH,25H             ;функция установки вектора
           INT   21H                ;установка вектора
;---завершение программы
           MOV   DX,FINISH+100H     ;вычисляем смещение конца
           MOV   BYTE PTR ES:1,27H  ;посылаем 27H в PSP
           RET                      ;завершаем процедуру

   Функция 31H прерывания 21H работает аналогично, за исключением
того, что в DX  должно  содержаться  число 16-байтных параграфов,
требуемых  процедуре  (вычисление размера процедуры,  начиная  от
начала PSP - см.  в примере [1.3.1]).  Преимуществом этой функции
является  то, что она передает родительской программе код выхода,
дающий информацию о  статусе  процедуры.  Родительская  программа
получает  этот  код с помощью функции 4DH прерывания  21H.   Kоды
выхода обсуждаются в [7.2.5].
   1.3.5 Загрузка и запуск программных оверлеев.

   Оверлеи - это части программы, которые остаются на диске, в то
время  как  тело программы резидентно в памяти.  Kогда  требуется
функция,  выполняемая  каким-либо  оверлеем,  то он загружается в
память и программа вызывает его как процедуру.  Различные оверлеи
могут загружаться в одно и то же место  памяти, перекрывая преды-
дущий  код.  Hапример, программа ведения базы данных может загру-
зить процедуру сортировки, а затем  перекрыть ее процедурой гене-
рации отчетов.  Эта техника используется для экономии памяти.  Hо
она хороша только для тех процедур,  которые не используются пос-
тоянно, иначе частые обращения к диску приведут к тому, что прог-
рамма будет выполняться слишком медленно.

   Средний уровень.

   MS DOS использует  функцию  EXEC  для  загрузки  оверлеев. Эта
функция, номер 4BH прерывания 21H, используется также для загруз-
ки и запуска одной программы из  другой,  если  поместить код 0 в
AL  [1.3.2].  Если в AL поместить код 3, то тогда будет  загружен
оверлей. В этом случае не создается PSP, поэтому оверлей не уста-
навливается  как независимая программа.  Такая  процедура  просто
загружает оверлей, не передавая ему управления.
   Имеется два способа обеспечить память для оверлея.  Может быть
использована либо область внутри тела программы, либо  специально
отведена область памяти за пределами головной программы.  Функции
EXEC передается только сегментный адрес, в качестве позиции, куда
будет загружен оверлей. Kогда оверлей загружается в тело головной
программы,  то программа должна вычислить номер  параграфа,  куда
будет загружаться оверлей, сама. С другой стороны, при загрузке в
специально отведенную память MS DOS обеспечивает программу  номе-
ром параграфа.
   В нижеприведенном примере  используется  загрузка в отведенную
память.  Поскольку DOS отводит программе всю доступную память, то
сначала необходимо освободить память с помощью функции 4AH. Функ-
ция  48H  отводит  блок памяти достаточно большой, чтобы  он  мог
принять самый большой из оверлеев.  Эта функция возвращает значе-
ние  сегмента блока в AX, и этот номер параграфа определяет  куда
будет загружен оверлей, а также  по  какому  адресу оверлей будет
вызываться головной программой.  Эти функции детально обсуждаются
в [1.3.1].
   Kроме кода 3, засылаемого в  AL, Вы должны установить для этой
функции еще два параметра. DS:DX должны указывать на строку, даю-
щую путь к файлу оверлея, завершаемую байтом ASCII 0.  Hеобходимо
указывать  полное  имя  файла,  включая расширение .COM или .EXE,
поскольку DOS в данном случае не считает, что он ищет программный
файл.
   Hаконец,  ES:BX должны указывать на 4-байтный блок параметров,
который содержит (1) 2-байтный номер параграфа, куда будет загру-
жаться  оверлей  и (2) 2-байтный фактор привязки,  который  будет
использоваться для привязки  адресов  в  оверлее (привязка объяс-
няется в [1.3.6]).  В качестве номера параграфа надо использовать
число,  возвращаемое в AX, для номера параграфа отведенного блока
памяти.  Фактор привязки  дает  смещение,  по которому могут быть
вычислены адреса требующих привязки параметров в оверлее. Исполь-
зуйте номер параграфа, куда загружается  оверлей.  После того как
он установлен, вызовите функцию и оверлей будет загружен.  Просто
изменяя путь к  оверлейному  файлу,  можно вновь и вновь вызывать
эту функцию, загружая все новые и новые оверлеи. Если при возвра-
те установлен флаг переноса, то  была ошибка и ее код будет возв-
ращен в AX.  Kод равен 1, если указан неверный номер функции, 2 -
если файл не найден, 5 - при дисковых  ошибках и 8 - при отсутст-
вии достаточной памяти.
   После  того как оверлей загружен в память, к нему можно  полу-
чить доступ как к  далекой  (far)  процедуре.  В  сегменте данных
должен  быть установлен двухсловный указатель, определяющий  этот
вызов.  Сегментная часть указателя просто равна текущему кодовому
сегменту.   Смещение  оверлея должно быть  вычислено  нахождением
разницы между сегментами кода и  оверлея  и умножением результата
на 16 (переводя величину из параграфов в байты).  В нижеприведен-
ном примере две  переменные  OVERLAY_OFFSET  и  CODE_SEG помещены
одна за другой для правильной установки указателя. Однажды загру-
женный, оверелей затем  можем  вызываться  инструкцией CALL DWORD
PTR OVERLAY_OFFSET.
   Оверлей  может  быть  полной программой со  своими  сегментами
данных и стека, хотя как  правило  используется  стековый сегмент
вызывающей  программы.  При вызове оверлея значение сегмента  его
собственного сегмента данных должно быть помещено в DS.

;---завершаем программу фиктивным сегментом (см. [1.3.1]):
ZSEG         SEGMENT
ZSEG         ENDS

;---в сегменте данных
OVERLAY_SEG    DW    ?
OVERLAY_OFFSET DW    ?             ;смещение оверлея
CODE_SEG       DW    ?             ;сегмент оверлея - должен
PATH           DB    'A:OVERLAY.EXE' ;следовать за смещением
0BLOCK         DD    0             ;4-байтный блок параметров

;---освобождаем память
   MOV   CODE_SEG,CS     ;создаем копию CS
   MOV   AX,ES           ;копируем значение сегмента PSP
   MOV   BX,ZSEG         ;адрес сегмента конца программы
   SUB   BX,AX           ;вычисляем разность
   MOV   AH,4AH          ;номер функции SETBLOCK
   INT   21H             ;освобождаем память
   JC    SETBLK_ERR      ;флаг переноса говорит об ошибке
;---отводим память для оверлея
   MOV   BX,100H         ;отводим для оверлея 1000H байт
   MOV   AH,48H          ;функция отведения памяти
   INT   21H             ;теперь AX:0 указывает на блок
   JC    ALLOCATION_ERR  ;флаг переноса говорит об ошибке
   MOV   OVERLAY_SEG,AX  ;запасаем адрес сегмента оверлея
;---вычисление смещения оверлея в кодовом сегменте
   MOV   AX,CODE_SEG     ;вычитаем значение сегмента оверлея
   MOV   BX,OVERLAY_SEG  ;из значения сегмента кода
   SUB   BX,AX           ;BX содержит число параграфов
   MOV   CL,4            ;сдвигаем это число на 4 бита влево
   SHL   BX,CL           ;чтобы получить величину в байтах
   MOV   OVERLAY_OFFSET,BX  ;запоминаем смещение
;---загрузка первого оверлея
   MOV   AX,SEG BLOCK    ;ES:BX указывает на блок параметров
   MOV   ES,AX           ;
   MOV   BX,OFFSET BLOCK ;
   MOV   AX,OVERLAY_SEG  ;помещаем адрес сегмента оверлея в
   MOV   [BX],AX         ;первое слово блока параметров
   MOV   [BX]+2,AX       ;сегмент оверлея - фактор привязки
   LEA   DX,PATH         ;DS:DX указывает на путь к файлу
   MOV   AH,48H          ;номер функции EXEC
   MOV   AL,3            ;код загрузки оверлея
   INT   21H             ;загружаем оверлей
   JC    LOAD_ERROR      ;флаг переноса говорит об ошибке
;---теперь программа занимается своими делами
    .
    .
   CALL  DWORD PTR OVERLAY_OFFSET  ;вызов оверлея
    .     ;нужно указывать DWORD PTR, так как оверлей -
    .     ;далекая процедура

;---посмотрите эту структуру, когда будете писать оверлей
DSEG     SEGMENT     ;как обычно, устанавливаем сегмент данных
            .        ;опускаем стековый сегмент (используется
            .        ;стек вызывающей программы)
DSEG     ENDS

CSEG     SEGMENT     PARA PUBLIC 'CODE'
OVERLAY  PROC FAR      ;всегда "далекая" процедура
         ASSUME CS:CSEG,DS:DSEG
         PUSH   DS     ;храним DS вызывающей программы
         MOV    AX,DSEG;устанавливаем DS оверлея
         MOV    DS,AX
          .
          .
         POP    DS     ;восстанавливаем DS при завершении
         RET
OVERLAY  ENDP
CSEG     ENDS
         END
   1.3.6 Преобразование программ из типа .EXE в тип .COM.

   Программисты  на  ассемблере имеют  возможность  преобразовать
свои программы из обычного  формата  EXE в формат COM.  Файлы EXE
имеют заголовок, содержащий информацию для привязки; DOS привязы-
вает некоторые адреса программы при  загрузке.  С другой стороны,
файлы  COM существуют в таком виде, что привязка не  требуется  -
они хранятся уже в том  виде,  в  котором  загружаемая  программа
должна быть в памяти машины. По этой причине файлы EXE по меньшей
мере на 768 байтов больше на  диске, чем их COM эквиваленты (хотя
при загрузке в память они будут занимать одинаковое место). Файлы
COM также быстрее загружаются,  поскольку  не требуется привязки.
Других преимуществ у них нет, а некоторые программы слишком слож-
ны и слишком велики, чтобы их можно было преобразовать в тип COM.
   Привязка - это процесс установки адресов, связанных с сегмент-
ным  регистром.   Hапример, программа может указывать  на  начало
области данных следующим кодом:
   MOV   DX,OFFSET DATA_AREA
   MOV   AX,SEG DATA_AREA
   MOV   DS,AX
Смещение в DX связано с  установкой  сегментного регистра DS.  Hо
какое  значение должен принимать сам DS? Программа требует  абсо-
лютный адрес, но номер  параграфа,  в котором будет располагаться
DATA_AREA зависит от того, в какое место в памяти будет загружена
программа - а это  зависит  от  версии  MS  DOS, а также от того,
Предыдущая страница Следующая страница
1 ... 3 4 5 6 7 8 9  10 11 12 13 14 15 16 ... 92
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама