Страница 16 из 20 1.3.2 Запуск одной программы из другой. MS DOS обеспечивает функцию EXEC (номер 4BH прерывания 21H), реализующую вызов одной программы из другой. Первая программа называется "родителем", а загружаемая и запускаемая - "потомком". Высокий уровень. В Бейсик версии 3.0 введена команда SHELL. Со значительными ограничениями она позволяет бейсиковской программе загрузить и выполнить другую программу. Формат этой команды SHELL ком_строка. Командная строка может быть просто именем программы или она может содержать кроме имени параметры, которые обычно следуют за именем программы в командной строке. Если ком_строка не указана, то загружается копия COMMAND.COM и появляется запрос операционной системы. В этот момент можно выполнить любую команду MS DOS, а по завершению вернуть управление бейсиковской программе, введя ко- манду EXIT. Имеется ряд ограничений при использовании SHELL. Если загру- жаемая программа меняет режим работы дисплея, то он не будет автоматически восстановлен при возврате. Перед загрузкой програм- мы все файлы должны быть закрыты, и это не может быть программа, которая остается резидентной после завершения. Обсуждение ряда других проблем содержится в руководстве по Бейсику. Средний уровень. Функция 4BH более сложна, чем остальные, требуя четырех подго- товительных шагов: 1. Подготовить в памяти место, доступное программе. 2. Создать блок параметров. 3. Построить строку, содержащую накопитель, путь и имя прог- раммы. 4. Сохранить значения регистров SS и SP в переменных. Поскольку при загрузке программы MS DOS выделяет ей всю дос- тупную память, то необходимо освободить место в памяти. Если не освободить часть памяти, то не будет места для загрузки второй программы. В [1.3.1] объяснено как это сделать с помощью функции SETBLOCK. После того как память освобождена, Вы должны просто поместить в BX требуемое число 16-байтных параграфов, заслать 4AH в AH и выполнить прерывание 21H, делая доступным программе именно то число параграфов, которое ей требуется. Блок параметров, на который должны указывать ES:BX это 14-байтный блок блок памяти, в который Вы должны поместить сле- дующую информацию: DW сегментный адрес строки среды DD сегмент и смещение командной строки DD сегмент и смещение первого FCB DD сегмент и смещение второго FCB Строка среды - это строка, состоящая из одной или более специ- фикаций, которым следует MS DOS при выполнении программы. Элемен- ты строки среды такие же, как и те что можно обнаружить в диско- вом файле CONFIG.SYS. Например, в строку может быть помещено VERIFY = ON. Просто начните строку с первого элемента, завершив его символом ASCII 0, потом запишите следующий и т.д. За послед- ним элементом должны следовать два символа ASCII 0. Строка должна начинаться на границе параграфа (т.е. ее адрес по модулю 16 дол- жен быть равен нулю). Это вызвано тем, что соответствующий вход в блоке параметров, указывающий на строку, содержит только 2-байт- ное сегментное значение. Все это не нужно, если новая программа может работать с той же строкой среды, что и программа "роди- тель". В этом случае надо просто поместить два символа ASCII 0 в первые 2 байта блока параметров. Следующие 4 байта блока параметров указывают на командную строку для загружаемой программы. "Командная строка" - это сим- вольная строка, определяющая способ работы программы. При загруз- ке программы из DOS она может иметь вид вроде EDITOR A:CHAPTER1\ NOTES.MS. При этом вызывается редактор и ему передается имя файла в подкаталоге накопителя A для немедленного открытия. Когда Вы подготавливаете командную строку для EXEC, то надо включать толь- ко последнюю часть информации, но не имя загружаемой программы. Перед командной строкой должен стоять байт, содержащий длину этой строки, и она должна завершаться символом <ВК> (ASCII 13). Последние 8 байтов блока параметров указывают на управляющие блоки файлов (FCB). FCB содержит информацию об одном или двух файлах, указанных в командной строке. Если открываемых файлов нет, то надо заполнить все 8 байт символом ASCII 0. В [5.3.5] объяснено, как работает FCB. Начиная с версии MS DOS 2.0, исполь- зование FCB необязательно и Вы можете не включать информацию FCB, вместо этого используя новую конвенцию дескриптора файлов (file handler), в которой доступ к файлу предоставляется по кодовому номеру, а не через FCB (также обсуждается в [5.3.5]). Наконец, Вы должны построить строку с указанием накопителя, пути и имени файла. Эта строка именует загружаемую программу. DS:DX указывает на эту строку при выполнении EXEC. Эта строка - стандартная строка ASCIIZ, т.е. ничего более, чем стандартная спецификация файла, завершаемая кодом ASCII 0. Например, это может быть B:\NEWDATA\FILER.EXE, где символом обозна- чен код ASCII 0. После того как вся указанная информация подготовлена, остается последняя задача. Поскольку все регистры будут изменены вызывае- мой задачей, то надо сохранить сегмент стека и указатель стека, с тем чтобы они могли быть восстановлены, когда управление будет возвращено вызвавшей задаче. Для их сохранения создайте перемен- ные. Поскольку значение регистра DS также будет изменено, то эти переменные не могут быть найдены, до тех пор пока не будут повто- рены операторы MOV AX,DSEG и MOV DS,AX. После того как SS и SP сохранены, поместите 0 в AL, для выбора операции "загрузка и запуск" (EXEC используется также для оверлеев [1.3.5]). Затем поместите 4AH в AH и вызовите прерывание 21H. В этот момент запу- щены две программы, причем программа "родитель" находится в оста- новленном состоянии. MS DOS предоставляет возможность программе потомку передать родителю код возврата, таким образом могут быть переданы ошибки и статус. В [7.2.5] объяснено как это сделать. Что касается самой функции запуска, то при возникновении ошибки устанавливается флаг переноса, а регистр AX в этом случае будет возвращать 1 - для неправильного номера функции, 2 - если файл не найден, 5 - при дисковой ошибке, 8 - при нехватке памяти, 10 - если неправильна строка среды и 11 - если неверен формат.
Приводимый пример - простейший из возможных, но часто больше ничего и не надо. Здесь оставлен нулевым блок параметров и не создана строка среды. Это означает, что загружаемой программе не будет передаваться командная строка и что среда будет такой же, как и для вызывающей программы. Вы должны только изменить распре- деление памяти, создать имя и (пустой) блок параметров и сохра- нить значения SS и SP. ;---в сегменте данных FILENAME DB 'A:TRIAL.EXE',0 ;загружаем TRIAL.EXE PARAMETERS DW 7DUP(0) ;нулевой блок параметров KEEP_SS DW 0 ;переменная для SS KEEP_SP DW 0 ;переменная для SP ;---перераспределение памяти MOV BX,ZSEG ;получить # параграфа конца MOV AX,ES ;получить # параграфа начала SUB BX,AX ;вычислить размер программы MOV AH,4AH ;номер функции INT 21H ;перераспределение ;---указываем на блок параметров MOV AX,SEG PARAMETERS ;в ES - сегмент MOV ES,AX ; MOV BX,OFFSET PARAMETERS ;в BX - смещение ;---сохранить копии SS и SP MOV KEEP_SS,SS ;сохраняем SS MOV KEEP_SP,SP ;сохраняем SP ;---указываем на строку имени файла MOV DX,OFFSET FILENAME ;смещение - в DX MOV AX,SEG FILENAME ;сегмент - в DS MOV DS,AX ; ;---загрузка программы MOV AH,4BH ;функция EXEC MOV AL,0 ;выбираем "загрузку и запуск" INT 21H ;запускаем задачу ;---впоследствии, восстанавливаем регистры MOV AX,DSEG ;восстанавливаем DS MOV DS,AX ; MOV SS,KEEP_SS ;восстанавливаем SS MOV SP,KEEP_SP ;восстанавливаем SP ;---в конце программы создаем фиктивный сегмент ZSEG SEGMENT ;см. [1.3.1] ZSEG ENDS |