На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 3 / Функция 4Bh - загрузка и выполнение программ Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Функция 4Bh - загрузка и выполнение программ

Резидентные подпрограммы и RTL очень часто инициируются с помощью входного файла пользователя или командного файла, но при случае программе может понадобиться загрузить другую программу в память, либо использовать ее в качестве оверлейной (перекрываемой) программы, или как часть процесса установки резидентной подпрограммы. В любом случае, первоначальная программа называется порождающей (parent), а другая программа порожденной (child).


MS-DOS для таких случаев обеспечивает функцию загрузки и выполнения программ с кодом 4Bh. Эта функция может выполняться в одном из двух режимов. Первый режим - выполнение программы - предназначен для загрузки программного файла в память и выполнения этой программы. Порожденная программа выполняется без управления со стороны порождающей программы. Этот режим выбирается путем установки регистра AL в нулевое значение и установкой соответствующих значений в блоке параметров. Параметры, требуемые для выполнения функции 4Bh, показаны на рис.3-13, а пример загрузки и выполнения программы содержится в программе LOAD (загрузка), показанной в листинге 3-8. Макробиблиотека, упоминаемая в программе LOAD, является такой же, какая использована в программе EXRTL (смотри листинг 3-5).



             Листинг 3-8. Загрузка программы с помощью функции MS-DOS
                                   4Bh (AL = 0)
         ----------------------------------------------------------------

         ;======LOAD.ASM - Этот файл вырабатывает файл типа .COM ========
         ; LOAD имеет возможность загрузки и выполнения другой программы.
         ; LOAD вызывается путем набора следующей информации:
         ;      "LOAD <имя файла> < аргументы программы>
         ; Между LOAD и именем файла, а также между именем файла и аргу-
         ; ментами должен быть только один символ "пробел". Имя файла
         ; должно включать расширение.
         ;
         NEWPROG EQU     82h  ;  адрес загрузки командной строки в PSP
         NEWSTR  EQU     81h  ; адрес строки в PSP (пробел 20h)
         NEWLEN  EQU     80h  ; адрес длины командной строки
         ;
         INCLUDE STDMAC.INC      ; включение описания макробиблиотеки
         ;====== ПРОГРАММНАЯ СЕКЦИЯ =====================================
         ;
         code_seg SEGMENT
                 ASSUME  cs:code_seg
                 ASSUME  ds:code_seg
                 ORG     0
         SEG_ORG EQU     $
         main    PROC    FAR
         start:
                 mov     sp,offset TOP_STK ; установка вершины стека
         ;
         ; Грамматический разбор командной строки для поиска конца или
         ; пробела. Преобразование имени программы в строку ASCIIZ.
         ;
                 mov     bx,0              ; очистка BX
                 mov     bl,NEWLEN[bx]     ; получение длины ком.строки
                 or      bl,bl             ; проверка длины строки
                 jnz     cmd_ok
                 @DisStr bad_cmd           ; ошибка в командной строке
                 jmp     exit
         cmd_ok:
                 dec     bx                ; вычитание 1 для пробелов
                 mov     cx,bx             ; копирование длины в счетчик
                 mov     di,NEWPROG        ; поиск адреса (1-й не пробел)
                 mov     al,' '            ; поиск значения (пробел)
                 repne   scasb             ; поиск расширения файла
                 pushf                     ; сохранение результата поиска
                 sub     bx,cx             ; получение оставшегося счетчи-
                 popf                      ; ка и результатов поиска
                 jz      set_zb            ; нулевой флажок => параметры
                                           ; (найден пробел)
                 inc     bx                ; ненулевой флажок подразуме-
                                           ; вает конец строки
         set_zb:                           ; преобразование командной
                                           ; строки в ASCIIZ
                 mov     byte ptr NEWSTR[bx],0
                 mov     cmd_buf,cl        ; установка длины строки пара-
                                           ; метра
                 cmp     cl,0              ; достигнут конец строки?
                 jle     free_mem          ; нет параметров команды
         ;
         ; Прием остатка строки и передача его в текстовый буфер команд-
         ; ной строки для вызываемой программы
         ;
                 inc     cl                ; передача CR
                 mov     si,di             ; передача исходного индекса
                 mov     di,offset cmd_txt ; или установка индекса назна-
                                           ; чения
                 rep     movsb             ; передача остатка строки
                 add     cmd_buf,1         ; увеличение количества проб.
         ;
         ; Освобождение системной памяти для загрузчика и вызываемой
         ; программы. Сокращение блока распределения до необходимого
         ; минимума.
         ;
         free_mem:
                 mov     bx,(offset LST_BYT - SEG_ORG + 15) shr 4
                 mov     ah,04Ah           ; ES содержит адрес PSP
                 @DosCall                  ; модификация распред. памяти
                 jnc     modify_ok
                 push    ax                ; (помещение в стек при ошиб-
                                           ; ке)
                 @DisStr fail4A            ; сообщение об ошибке или
                                           ; завершение, если сбой
                 jmp     error
         ;
         ; Установка блока параметров и регистровых параметров для
         ; вызова функции загрузки или выполнения программы.
         modify_ok:
                 mov     ax,cs             ; установка всех параметров
                 mov     p1,ax             ; сегментов в этот сегмент
                 mov     p2,ax
                 mov     p3,ax
                 mov     dx,offset NEWPROG
                 mov     bx,offset param_block
                 mov     spoint,sp         ; сохранение указателя стека
                 mov     ax,4B00h          ; функция загрузки или выпол-
                                           ; нения программы
                 @DosCall
         ;
         ; Восстановление регистров сегмента и указателя стека после
         ; вызова.
         ;
                 mov     cx,cs             ; дублирование CS во все сегм.
                 mov     ss,cx          ; сначала восстанавливается стек
                 mov     sp,cs:spoint   ; восстановление указателя стека
                 mov     ds,cx
                 mov     es,cx
                 jnc     exit      ; выход из программы, если все хорошо
                 push    ax                ; сохранение кода ошибки
                 @DisStr fail4B            ; вывод ошибки, если сбой
         ;
         ; Грамматический разбор кода ошибки, возвращаемого системой
         ; и отображение соответствующего текста сообщения
         ;
         error:
                 pop     ax        ; обратное получение кода ошибки
         @Case   ax,<+,2,7,8,9,10h,11h>,
                 mov     dx,offset err0    ; плохой код ошибки - неравны
                 jmp     merge
         em1:    mov     dx,offset err1    ; неправильная функция
                 jmp     merge
         em2:    mov     dx,offset err2    ; файл не найден
                 jmp     merge
         em7:    mov     dx,offset err7    ; память засорена
                 jmp     merge
         em8:    mov     dx,offset err8    ; недостаточно памяти
                 jmp     merge
         em9:    mov     dx,offset err9    ; неправильный блок памяти
                 jmp     merge
         em10:   mov     dx,offset err10   ; неправильная среда
                 jmp     merge
         em11:   mov     dx,offset err11 ; неправильный формат файла .EXE
                 jmp     merge
         merge:  mov     ah,09h            ; отображение строки
                 @DosCall
         exit:   mov     ax,04C00h         ; завершение при окончании
                 @DosCall
         main    ENDP
         ;
         bad_cmd db      'Error in Command Line',CR,LF,'$'
         ; ошибка в командной строке
         fail4A  db      'Failed to Modify Allocated Memory Blocks'
                 db      CR,LF,'$'
         ; сбой при модификации блока распределенной памяти
         fail4B  db      'Failed to Load Program Overlay',CR,LF,'$'
         ; сбой при загрузке программного оверлея
         err0    db      '>>> UNKNOWN ERROR CODE <<<',CR,LF,'$'
         ; неизвестный код ошибки
         err1    db      '>>> invalid function <<<',CR,LF,'$'
         ; неправильная функция
         err2    db      '>>> file not found <<<',CR,LF,'$'
         ; файл не найден
         err7    db      '>>> memory arena trashed <<<',CR,LF,'$'
         ; память засорена
         err8    db      '>>> not enough memory <<<',CR,LF,'$'
         ; недостаточно памяти
         err9    db      '>>> invalid memory block <<<',CR,LF,'$'
         ; неправильный блок памяти
         err10   db      '>>> bad environment <<<',CR,LF,'$'
         ; неправильная среда
         err11   db      '>>> bad .EXE file format <<<',CR,LF,'$'
         ; неправильный формат файла .EXE
         ;
         spoint  dw      ?                 ; память для указателя стека
         param_block     label word
                 dw      0    ; используемая среда порождающей программы
                 dw      offset cmd_buf
         p1      dw      ?                 ; сегмент командной строки
                 dw      5Ch               ; сегмент FCB #1 или смещение
         p2      dw      ?
                 dw      6Ch               ; сегмент FCB #2 или смещение
         p3      dw      ?
         cmd_buf db      ?                 ; длина командной строки
                 db      ' '               ; всегда предполагается пробел
         cmd_txt db      80 dup (?)        ; 80 символов
         ;
         ; Описание локального стека
         EVEN                              ; слово выравнивания стека
         stack   db      32 dup ('stack   ') ; локальный стек
         TOP_STK EQU     $-2           ; установка адреса вершины стека
         LST_BYT EQU     $                 ; последний байт в программе
         ;
         code_seg ENDS
                 END     start
         ----------------------------------------------------------------

Второй режим называется Load Overlay (загрузка оверлейных программ). Хотя в этом режиме загружается программный файл, режим Load Overlay не выполняет вызов программы. Вместо этого управление сразу же возвращается в вызывающую программу. Этот режим выбирается путем установки в регистре AL значения, равного 3. Блок параметров для этого режима показан на Рис. 3-14.


В любом режиме функционирования перед выполнением функции загрузки и выполнения программы блок начального распределения вызывающей программы должен быть приведен в исходное состояние для освобождения пространства памяти. MS-DOS загружает программы, используя программный загрузчик файла COMMAND.COM, который не является резидентной частью файла COMMAND.COM. Программный загрузчик должен считать в память сам себя с диска перед тем, как он сможет загрузить программу пользователя или оверлейную программу. (Это также предполагает, что в системе для этой функции должен работать диск, содержащий файл COMMAND.COM).



             РЕГИСТРЫ                                    ВНЕШНИЙ СЕГМЕНТ
                                                       .----------------.
         AX:4B03(шестн.) <------ Функция Load Overlay  |       ...      |
                                                       |----------------|
         BX:указатель на имя файла в коде ASCIIZ ----->| имя файла/пути |
                                                       |  нулевой байт  |
         DX: указатель на блок параметров ------.      |----------------|
                                                |      |       ...      |
                                                |       \/\/\/\/\/\/\/\/
                                                |
         Адрес       ПАМЯТЬ СИСТЕМЫ             |        СЕГМЕНТ ДАННЫХ
         0000:0000 .----------------.           |      .----------------.
                   |Система или по- |           |      |                |
                   |рождающая прог- |           |      |       ...      |
                   |    рамма       |           |      |                |
                   |      ...       |            ----->|----------------|
                   |                |                  |Адрес загрузоч- |
         xxxx:0000 |----------------|<-----------------|ного сегмента   |
                   | Программный код|                  |----------------|
                   |      ...       |                  |Фактор настройки|
                   |----------------|                  |----------------|
                   |                |                  |                |
                    \/\/\/\/\/\/\/\/                    \/\/\/\/\/\/\/\/

               Рис.3-14. Блок параметров для функции 4Bh (al = 3) -
                   LOAD OVERLAY (Загрузка оверлейной программы)

Между загрузкой оверлейной и исполнимых программ имеется су- щественное отличие. Оверлейная программа загружается под управле- нием порождающей программы по адресу, определенному порождающей программой, и считается частью порождающей программы. Программные файлы, предназначенные для выполнения (функция 4Bh с регистром AL = 0), загружаются по адресу, выбираемому системой MS-DOS, и рас- сматриваются как отдельная программа.


НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz