|
|
|
|
Загрузка резидентных подпрограмм из командной строки
В MS-DOS имеется несколько способов, которые могут быть использованы для загрузки образа программы в память. Диапазон этих способов простирается
от загрузки программы из командной строки до подпрограмм начальной загрузки нижнего уровня, передающих программный код из абсолютного места на
диске в фиксированные ячейки памяти. Наиболее простым способом является способ использования загрузчика командной строки MS-DOS, представляющий собой
простой запрос для выполнения программы. Резидентные программы, такие как, например, RTL, загружаются в память подобно любой другой программе.
Однако, после того, как резидентная программа загружена и начала выполняться посредством предложения ее инициализации, она завершается использованием
специального выхода: функции с кодом 31h ("сохранить процесс") или вектора прерывания 27h ("завершить, но оставить резидентной"). Рекомендуемой
процедурой является использование функции с кодом 31h прерывания 21h, которая демонстрируется в листинге 3-4.
Функция с кодом 31h имеет два параметра: необязательный параметр код возврата, используемый для указания состояния при выходе из подпрограммы, и
обязательный параметр, представляющий собой значение размера блока памяти в параграфах, которое остается распределенным за процессом. При вызове функции
MS-DOS резервирует запрошенное количество памяти, начиная с адреса PSP (сегмента программого префикса). Это происходит почти также как и при вызове
функции "Модифицировать блок распределенной памяти" с адресом PSP и требуемым размером. В случае функции "сохранить процесс" MS-DOS знает, что блок,
размер которого должен быть модифицирован, начинается с адреса PSP, так что параметр не требуется.
Листинг 3-4. Функция с кодом 31h - "Сохранить процесс"
----------------------------------------------------------------
; используемый тип .COM
program segment
ORG 0
seg_org equ $
ORG 0100h
start:
...
mov dx,(offset last_byte - seg_org + 15) shr 4
mov ah,31h ; сохранить процесс
int 21h ; вызов MS-DOS
...
last_byte:
program ends
end start
; используемый тип .EXE
...
mov ax,es ; получение адреса PSP
mov dx,seg end_addr ; получение адреса посл.сегм.
sub dx,ax ; получение размера прогр-мы
mov ah,31h ; сохранить процесс
int 21h ; вызов MS-DOS
...
program ends
end_addr segment
end_addr ends
end start
----------------------------------------------------------------
|
В главе 2 был представлен набор формул для вычисления размера программы в параграфах. Эти формулы могут быть использованы с функцией "Сохранить
процесс" также как и с функцией "Модифицировать блок распределенной памяти". При использовании этих формул в резидентных программах, появилось
соответствующее уравнение, как показано в листинге 3-4. Заметим, что хотя функция "Сохранить процесс" и не требует адреса PSP, программам типа .EXE
необходимо сохранять адрес PSP при выходе с целью вычисления размера программы.
Т.к. память резервируется в начале PSP, резидентные подпрограммы не должны загружаться в верхнюю часть блока памяти (например, путем использования
переключателя /high компоновщика MS-LINK). Если подпрограмма загружается в верхнюю часть памяти, то она станет незащищенной при завершении резидентной
подпрограммы, т.к. сохраняемый блок памяти размещается в начале блока памяти. Подпрограмма сама будет размещаться выше пространства резервируемой памяти.
Когда подпрограмма станет таким образом незащищенной, MS-DOS может загрузить на то же самое место памяти другую программу или нерезидентную часть
файла COMMAND.COM, затирая резидентную подпрограмму.
В любом случае, переключатель /high компоновщика MS-LINK затрагивает только программы типа .EXE. Когда конвертирующая программа EXE2BIN для файла
.COM удалит маркер "загрузка высокая", MS-DOS будет загружать программу с начала PSP.
Другим способом инстоляции резидентных программ является прерывание "завершить и оставить резидентной" int 27h, оставленное из ранних версий MS-DOS.
Способ использования прерывания int 27h имеет ряд недостатков, которые сводят на нет использование этого способа. В отличие от функции "Сохранить
процесс" (Keep Process), прерывание int 27h не требует адреса блока памяти (задаваемого адресом PSP), а требует этот адрес в регистре CS. Только
файлы типа .COM имеют адрес PSP в регистре программного сегмента, затрудняя использование этой функции в программах типа.EXE. (Как выполнить
изменение регистра CS и еще выполнить программу?) Кроме того, параметр размер указывается в байтах, а не в параграфах, что ограничивает размер
программы, который может быть сохраненным до 64 Кбайт (максимальный размер программы типа .COM). Единственным достоинством этой функции является то,
что в качестве параметра может быть использовано без преобразования смещение последнего адреса, как показано ниже:
...
mov dx,offset last_byte ; получение количества байтов
int 27h ; завершение и оставить резидентной
...
last_byte:
program ends
end start
|
Фирма "Майкрософт" рекомендует для всех вновь разрабатываемых и для всех существующих модернизированных программ преобразовать это прерывание в
функцию с кодом 31h. При выполнении преобразования не забудьте модифицировать параметр размер (Size) из байтов в параграфы.
|
|