Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Организация дочерних процессов



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

Программа, загруженная функцией Ехес в память, включает три важных для программирования компонента: окружение, префикс программного сегмента и собственно программу, которая (в случае файла .ЕХЕ) может состоять из нескольких сегментов и в принципе занимать несколько несвязных участков памяти. Поскольку окружение и сама программа рассматривается DOS, как отдельные блоки памяти, и та, и другая структура предваряется блоком управления памятью (БУП) размером 16 байт. С помощью этих блоков DOS ведет учет свободной и занятой памяти (рис.14.1).

В процессе начальной загрузки DOS создает так называемое окружение, в котором будут работать активизируемые программы и, прежде всего, командный процессор COMMAND.СОМ. Окружение представляет собой область памяти, в которой в виде символьных строк записаны значения переменных, называемых переменными окружения.

Каждая строка имеет формат

переменная = значение

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

 

Рис. 14.1. Запуск дочернего процесса

 

Окружение для командного процессора, создаваемое в процессе начальной загрузки, чаще всего содержит переменные COMSPEC, PROMPT и PATH, которые заносятся в окружение из файла AUTOEXEC.BAT, и может иметь, например, следующий вид:

COMSPEC=D:\DOS\COMMAND.COM

PROMPT=$p$g

PATH=D:\; D:\DOS; D:\UTIL

Первая строка описывает путь к файлу командного процессора COMMAND.СОМ. Системные и прикладные программы, загружаясь в память, могут затирать транзитную часть командного процессора, и после завершения такой программы командный процессор надо снова загрузить с диска. Система (конкретно - резидентная часть COMMAND.COM) берет имя и местонахождение файла с командным процессором из значения переменной окружения COMSPEC.

Строка с переменной PROMPT задает вид системного запроса, который в приведенном примере состоит из полного пути к текущему каталогу и изображения стрелки (если переменная PROMPT не определена, устанавливается стандартный системный запрос, который включает лишь имя текущего диска и стрелку; работать с таким запросом крайне неудобно).

Строка с переменной PATH определяет пути, которые автоматически просматриваются DOS при поиске на диске запущенной пользователем программы.

Пользователь может включить в окружение строки определения дополнительных переменных с помощью команды SET, При вводе этой команды с клавиатуры значения дополнительных переменных будут действовать только в данном сеансе работы на компьютере (до его перезагрузки). Если же включить команду SET в файл AUTOEXEC.BAT, она будет автоматически выполняться каждый раз при загрузке системы и значения дополнительных переменных будут определены всегда.

Многие общеупотребительные прикладные программы анализируют область памяти, выделяемую для окружения, и используют значения зарезервированных для этих программ переменных. Обычно в качестве значений таких переменных указываются пути к каталогам с вспомогательными файлами программ. Так, редактор Chiwriter анализирует с этой целью переменную CHIFILES, программы фирмы Microsoft - переменную ТМР т.д. Можно включать в окружение и "персональные" переменные, адресованные конкретной программе пользователя.

После того, как выполнена начальная загрузка DOS, активной программой (текущим процессом) становится командный процессор, который фактически ничего не делает, ожидая ввода команды с клавиатуры. Получив команду оператора на запуск программы (например, программы Р.ЕХЕ на рис. 14.1), COMMAND.COM, активизируя эту программу (с помощью функции DOS Exec), передает ей свое окружение. Практически это осуществляется путем копирования строк окружения в новую область памяти, которая обычно располагается перед загружаемой программой. Если загруженная программа по ходу своего выполнения в свою очередь активизирует дочерний процесс следующего уровня (с помощью той же функции Ехес), она еще раз копирует свое окружение, передавая его запускаемой ею программе. При этом родительский процесс может передать дочернему свое окружение в неизменном виде, а может включить в него новую информацию. Таким образом, каждая программа, загруженная в память, имеет собственную копию окружения, причем эти копии могут совпадать, а могут и различаться. После завершения программы и возврата управления родительскому процессу окружение дочерней программы уничтожается, и родительский процесс продолжает работать со своим собственным окружением.

Многие программы не используют переменные окружения и передача им окружения носит номинальный характер. С другой стороны, с помощью этого механизма родительские процессы могут передавать дочерним значительные объемы информации (максимальный размер блока окружения составляет 32 Кбайт).

Вторая структура данных, формируемая функцией Ехес при активизации вызываемой программы, PSP занимает объем 256 байт и фактически включается в состав загружаемой программы. В слово PSP с адресом 2Ch (относительно его начала) DOS помещает сегментный адрес окружения программы, а в область, начинающуюся с адреса 80h - хвост команды ( /S на рис.9.1). В байте по адресу 80h находится длина хвоста без учета завершающего команду кода 13, а затем располагаются сами параметры в виде символьной строки. С помощью хвоста командной строки запускаемой программе часто передаются ключи, управляющие ее работой, а также имена рабочих файлов. Так, программа Р.ЕХЕ могла быть запущена командой

>Р.ЕХЕ A:\WORKFILE.001 /S

в которой программе, помимо ключа /S, определяющего режим ее работы, передается еще и имя и местоположение рабочего файла WORKFILE.001. Если пользовательскую программу предполагается запускать с передачей ей каких-то параметров, то в программе должны быть строки извлечения хвоста команды из PSP и его анализа.

Для загрузки и выполнения дочерней программы родительская программа должна вызвать прерывание Int 21h с функцией 4Bh при следующем состоянии регистров:

AH = 4Bh;

AL = 00h (подфункция загрузки дочерней программы);

DS:DХ = адрес строки со спецификацией файла с дочерней программой;

ЕS:ВХ = адрес блока параметров.

Спецификация файла с дочерней программой должна быть однозначной и не может содержать шаблоны групповых операций. Спецификация должна включать в явной форме расширение .СОМ или .ЕХЕ. Если имя файла дано без указания пути, дочерняя программа ищется в текущем каталоге текущего диска.

Командный файл .ВАТ нельзя запустить с помощью функции Ехес непосредственно; вместо этого следует, используя Ехес, вызвать копию командного процессора COMMAND.COM и передать ему имя командного файла в хвосте команды после ключа /С.

Блок параметров служит для передачи функции Ехес необходимой информации и включает в себя адреса следующих объектов:

· окружения (сегментный адрес, однословная ячейка);

· хвоста комар (полный адрес, двухсловная ячейка);

· двух блоков управления файлами (FCB) (полные адреса, двухсловные ячейки).

Блок параметров и связанные с ним структуры данных выглядят, например, следующим образом:

parmblk dw envirseg                                  ;Сегмент окружения

dd cidtail                                      ;Адрес хвоста команды

dd fcb1                                         ;Адрес первого FCB

dd fcb2                                         ;Адрес второго FCB

chname db 'CHILD .EXE ',0                     ;Имя дочернего процесса

cmdtail   db 9,' FILE.TXT', 0Dh                 ;Хвост команды

fcb1       db 37 dup (0)                               ;Первый FCB

fcb2       db 37 dup (0)                               ;Второй FCB

envirseg segnent para 'ENVIR'                  ;Сегмент окружения

db 'COMSPEC=D:\DOS\COMMAND.COM',0

db 'WORKFILE=A:\FILES',0

db 0

envirseg ends

 

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

В приведенном выше примере сегмент окружения заполнен в родительской программе явным образом и содержит две переменные: системную переменную COMSPEC с описанием местоположения и имени командного процессора и индивидуальную переменную дочернего процесса WORKFILE, служащую, например, для передачи дочерней программе CHILD.EXE имени каталога с вспомогательными файлами. Этот пример несколько нетипичен в том отношении, что спецификация командного процессора обычно задается не в конкретной программе, а еще при запуске системы в файле AUTOEXEC.BAT командой SET COMSPEC=..., откуда она переписывается в окружение командного процессора. По мере активизации дочерних процессов значение переменной COMSPEC передается из окружения в окружение. Что же касается индивидуальной переменной (WORKFILE в приведенном примере), то она может быть включена в окружение дочернего процесса программным образом (как это показано в примере), либо установлена путем ввода с клавиатуры команды SET WORKFILE=...

В любом случае для использования информации, передаваемой через окружение, дочерняя программа извлекает из слова 2Ch в PSP физический адрес окружения и ищет затем в блоке окружения интересующие ее переменные.

Хвост команды используется для передачи дочерней программе параметров вызова, чаще всего имен рабочих файлов, а также ключей, определяющих режим работы программы. В процессе загрузки дочерней программы DOS перешлет хвост команды из блока параметров функции Ехес на его "законное" место - в префикс программного сегмента дочерней программы, где он будет располагаться начиная с адреса 80h. Для извлечения его из PSP и анализа в дочерней программе должны быть предусмотрены соответствующие программные строки.

В случае запуска программы с клавиатуры хвост команды вводится вслед за именем запускаемой программы вручную; при программной (динамической) активизации дочернего процесса хвост команды определяется в родительской программе, как это показано в примере.

В блоке параметров хвост команды должен иметь тот же формат, что и в PSP, т.е. начинаться с байта-счетчика, за которым следует символьная строка параметров. Завершается строка символом возврата каретки (0Dh), который не входит в счет байтов. Если в конкретном вызове дочерней программы параметры ей не передаются, хвост команды должен иметь вид db 0,0Dh.

Можно поступить еще проще, указав в блоке параметров ноль вместо адреса хвоста команды.

Блоки управления файлами (FCB) используются в настоящее время редко, так как операции над файлами удобнее выполнять с помощью дескрипторов. Однако формат блока параметров функции Ехес требует указания адресов двух FCB и наличия в родительской программе самих FCB размером 37 байтов каждый. Если заведомо известно, что загружаемая программа не будет использовать FCB, место под эти блоки можно не выделять. В поля блока параметров, предназначенные для адресов двух FCB, в этом случае записываются нули.

В простейшем варианте (наследуется окружение родительскийеля, а хвост команды и FCB отсутствуют) структура данных для вызова функции Ехес приобретают следующий вид:

parmblk dw 7 dup (0)

chname dd 'CHILD.EXE' ,0

 

Перед активизацией дочернего процесса родительская программа должна освободить достаточный для загрузки дочерней программы объем памяти. При нехватке памяти или при отсутствии запрашиваемого файла функция Ехес возвращает установленный бит CF.

Все файлы и устройства, открытые родительской программой с помощью выделения дескрипторов, дублируются в дочерней программе, т.е. дочерняя программа наследует все открытые дескрипторы родительской. Таким образом, обе программы могут совместно использовать одни и те же файлы, при этом операции ввода - вывода, выполняемые в дочерней программе, отражаются на состоянии дескрипторов родительской.

Активизировав дочерний процесс с помощью функции Ехес, DOS приостанавливает выполнение родительской программы до завершения дочерней. Дочерняя программа, завершая свое выполнение вызовом функции DOS 4Ch, может передать родительской код завершения с информацией об ошибках. Она может, в свою очередь, загружать другие программы с помощью той же самой процедуры, передавая управление через много уровней, пока в системе не исчерпается память.

Частным, но очень важным случаем активизации дочернего процесса является вызов из родительской программы второй копии командного процессора COMMAND.СОМ. Это дает возможность выполнять, не прерывая текущей программы, любые команды DOS, например, копирования файлов, проверки дискеты и т.д. Во многих случаях такая методика заметно упрощает программирование и расширяет возможности прикладных программ.

Для вызова с помощью функции Ехес командного процессора следует указать полную спецификацию его файла, которая обычно извлекается из окружения текущего процесса, хотя может быть задана непосредственно в полях данных программы.

При передаче командному процессору имени программы (в качестве хвоста командной строки) оно должно начинаться с ключа /С (как это делается при вызове команды DOS COMMAND, служащей для той же цели). Хвост команды может в этом случае иметь следующий вид:

Cmdtail  db 10,'/C DIR A:',0Dh

 

Здесь после загрузки второй копии командного процессора автоматически выполняется команда DOS DIR А:. Таким же образом можно выполнить и любую другую команду DOS или прикладную программу.

Можно выделить два варианта процедуры активизации второй копии командного процессора:

1. Командный процессор вызывается с ключом /С и указанием конкретной программы (команды DOS). Получив управление, командный процессор активизирует затребованную программу. После ее отработки управление немедленно передается родительскому процессу. Таким способом можно запускать не только команды DOS, но и командные файлы, которые нельзя активизировать с помощью функции Ехес непосредственно.

2. Командный процессор вызывается без ключа С и без имени конкретной команды. В этом случае командный процессор, получив управление, ожидает ввода команд DOS с клавиатуры. Пользователь может неограниченное время работать с DOS, вызывая любые команды DOS или прикладные программы. Для возврата в родительский процесс следует ввести команду EXIT. Такой режим (временный выход в DOS) широко используется в большинстве прикладных программ.

DOS позволяет дочернему процессу передать в вызвавший его родительский процесс код возврата (завершения). Этот код может принимать значение от 0 до 255. Обычно 0 считается кодом успешного завершения, а все остальные значения говорят об ошибках. Значение кода возврата формируется в дочерней программе по мере ее выполнения и передается родительской с помощью функции 4Ch:

mov AH,4Ch ;Функция завершения процесса

mov AL,errcode ;Код завершения

int 21h ;Передача управления

;родительскому процессу

 

Если программа запускается с клавиатуры (командой оператора), родительским процессом является COMMAND.COM, который и принимает код завершения. Для анализа кода завершения программу следует запускать не с клавиатуры, а из командного файла, содержащего строки анализа системной переменной ERRORLEVEL:

IF ERRORLEVEL 3 GOTO ЕЗ

IF ERRORLEVEL 2 GOTO E2

 

Если же программа запускается динамически из другой прикладной программы, то для получения кода возврата родительская программа сразу же после возврата в нее управления из дочерней должна выполнить функцию DOS 4Dh:

;Родительская программа

...

mov AH,4Bh            ; Функция Exec

;Заполнение регистров для функции Ехес

...

int 2lh                       ;Передача управления дочерней программе

mov AH,4Dh            ;Функция получения кода возврата

int 2lh                       ;Код возврата в AL

cmp AL,0

je ok

cmp AL,1

je errorl                     ;и т.д.

...

 

Пример 1. Запуск дочернего процесса. Написать и отладить в автономном режиме (запуск с клавиатуры) программу, предназначенную для использования в качестве дочернего процесса. Предусмотреть в этой программе операцию открытия некоторого файла и возврат (через функцию 4Ch) кода завершения (0 - файл открыт, 1 - файл открыть не удалось).

Написать программу, запускающую дочерний процесс и анализирующую, после его завершения, полученный код возврата. Ввиду ложности отладки такого комплекса, в обе программы следует включить анализ правильности выполнения функций DOS и вывод соответствующих диагностических сообщений.

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

Структура дочерней программы CHILD.ЕХЕ:

· вывод с помощью функции 40h диагностического сообщения "*Д* Дочерний процесс запущен";

· открытие файла с помощью функции 3Dh;

· анализ бита CF слова состояния процессора;

· вывод одного из двух диагностических сообщений, говорящих о результатах открытия файла;

· завершение программы (передача управления родительскому процессу) с кодом завершения 0, если CF=0 (файл открыт), и 1, если CF=1 (файл не найден).

Структура родительской программы PARENT.ЕХЕ:

· вывод с помощью функции 40h диагностического сообщения "*Р* Родительский процесс запущен";

· запуск с помощью функции 4Bh (Exec) дочернего процесса программы CHILD.EXE;

· анализ кода завершения функции Exec и вывод соответствующего диагностического сообщения, если дочерний процесс не запущен (например, если не освободилась память, необходимая для его загрузки);

· анализ с помощью функции 4Dh кода завершения дочернего процесса;

· в зависимости от значения кода завершения вывод одного из двух диагностических сообщений;

· завершение программы с помощью функции 4Ch.

 

Программа родительского процесса PARENT.EXE.

;Основные фрагменты программы

;Выведем на экран сообщение mes1 о запуске родительского процесса

...

;Освободим всю лишнюю память

...

;Запустим дочерний процесс

mov AX,_DATA      ;Настроим ES на сегмент данных

mov ES.AX                  

mov AH,4Bh            ;Функция Exec

mov AL,0                 ;Подфункция запуска программы

mov BX,offset parmblk    ;Адрес блока параметров

mov DX.offset chnane     ;Адрес имени дочерней программы

int 21h                          

jc errexec                 ;Ошибка запуска

;Проанализируем код возврата из дочернего процесса

mov AH,4Dh            ;Функция получения кода возврата

int 21h

cmp AL,1                 ;Наш код ошибки?

je errchild                 ;Да

;Выведем на экран сообщение mesZ

;об успешном завершении дочернего процесса

...

;Завершение программы

outprog: mov AX,4C00h  ;Функция завершения, код завершения = 0

int 21h                          

errchild:

;Выведем сообщение mes3 об ошибке при выполнении дочернего процесса

...

jmp outprog

errexec:

;Выведем на экран сообщение mes4 об ошибке при запуске дочернего процесса

...

jmp outprog

;Поля данных

chname db 'CHILD.ЕХЕ' ,0 ;Имя дочерней программы

parmblk dw 7 dup (0)

mes1     db '*P* Родительский процесс запущен',10,13

mes1len equ $-mes1

mes2     db '*P* Дочерний процесс отработал нормально',10,13

mes2len equ $-mes2

mes3     db '*P* Дочерний процесс завершился с ошибкой',10,13

mes3len equ $-mes3

mes4     db '*P* Дочерний процесс не активизирован',10,13

mes4len equ $-mes4

end myproc

 

Программа CHILD.EXE дочернего процесса.

;Основные фрагменты программы

;Выведем диагностическое сообщение mes1 об активизации дочернего процесса

...

:Сделаем попытку открыть файл

mov AH,3Dh            ;Функция открытия файла

mov AL,0                 ;Доступ для чтения

mov DX,offset fname ;Адрес имени файла

int 21h

jnc ok                        ;Переход, если CF=0

;Обработаем ошибку открытия файла

mov errcode,1         ;Код родительского процесса

;Выведем диагностическое сообщение mes2

...

jmp finend

;Завершим дочерний процесс

;Сначала выведем сообщение mes3 о нормальной работе

ok:

...

;И завершим программу с передачей родителю кода завершения

finend: mov AH,4Ch ;Функция завершения

mov AL,errcode      ;Код возврата

int 21h

;Поля данных

mes1     db '*Д* Дочерний процесс запущен',10,13

mes1len equ $-mes1

mes2     db '*Д* Файл не открылся!',10,13

mes2len equ $-mes2

mes3     db '*Д* Файл открылся и child завершается',10,13

mes3len equ $-mes3

fname   db 'FILE.TXT',0

errcode db 0

 

Пример 2. Передача параметров через хвост команды, Видоизменить программы примера 1 с целью демонстрации передачи параметров от родительского процесса дочернему. В качестве параметра использовать имя открываемого файла. Включить в программу CHILD.EXE анализ области PSP, содержащей хвост команды и извлечение оттуда имени открываемого файла. Отладить программу CHILD.EXE в автономном режиме (запуск с клавиатуры). Строка запуска программы CHILD.EXE теперь примет вид (если требуется открыть файл FILE.ТХТ):

>CHILD FILE.TXT

В программе PARENT.EXE вместо пустого хвоста команды указать конкретное имя открываемого файла. Отладить программный комплекс в целом.

Программа CHILD.EXE дочернего процесса

;Основные фрагменты программы

;Вывод диагностического сообщения mes1 о запуске дочернего процесса

...

;Инициализируем сегментные регистры ES и DS

push ES         ;ES указывает на PSP

push DS         ;DS указывает на сегмент данных.

pop ES           ;Обменяем их содержимое. Теперь

pop DS           ;DS->PSP, ES->сегмент данных

;Заберем хвост команды из PSP в fname

mov Sl,80h     ;Адрес хвоста команды в PSP

mov CL,[SI]    ;Отправим в CL счетчик байтов

dec CL            ;Скорректируем на пробел

xor СН,СН     ;СН=0

inc SI              ;Сдвинемся через счетчик байтов

inc SI              ;и пробел

mov Dl, offset ES:fname ;Куда переслать хвост

rep movsb      ;Перешлем весь хвост

push ES         ;Пусть снова

pop DS           ;DS->сегмент данных

;Сделаем попытку открыть файл с анализом флага CF

...

jnc ok              ;Переход, если CF = О

;Обработаем ошибку открытия файла (засылка кода завершения

;в ячейку errcode и вывод сообщения mes2 об ошибке открытия файла)

...

;Завершим дочерний процесс

;Сначала выведем сообщение mes3 о нормальной работе

ok:

...

;и завершим дочерний процесс с передачей родительскому кода завершения

outprog:

...

mes1     db '*Д* Дочерний процесс запущен',10,13

mes1len equ $-mes1

mes2     db '*Д* Файл не открылся! ',10,13

mes2len equ $-mes2

mes3     db '*Д* Файл открылся и child завершается',10,13

mes3len equ $-mes3

fname   db 80 dup (0)

errcode db 0                ;Начальное значение кода возврата

 

Пример 3. Извлечение переменной окружения в дочерней программе через адрес окружения в PSP. Видоизменить программы примера 1 с целью демонстрации передачи параметров запускаемой программе через ее окружение. В качестве параметра по-прежнему использовать имя открываемого файла, определяемого теперь не в хвосте команды, а в системном окружении, как значение переменной окружения WORKFILE. В этом случае, изменяя в системном окружении с помощью команды DOS SET значение переменной WORKFILE, можно заставить программу CHILD.ЕХЕ работать именно с этим файлом в качестве рабочего. Значение переменной WORKFILE устанавливается следующим образом:

>SET WORKFILE=FILE.TXT

если файл находится в текущем каталоге или

>SET WORKFILE=F:\MYDIR\FILE.TXT

если файл находится в произвольном каталоге.

 

Программа CHILD.EXE дочернего процесса

;Основные фрагменты программы

;Выведем диагностическое сообщение mes1 о запуске дочернего процесса

...

;Получим адрес окружения

mov AX,ES:2Ch Сегментный адрес окружения в PSP
mov ES,AX ES -> окружение

;Найдем в окружении подстроку 'WORKFILE='

;Сравним переменную в окружении с нашей

mov ВХ,0 ;ВХ-> начало имени
cld ;Поиск вперед
compr: mov СХ,lеn ;Длина нашей переменной
mov SI,offset envvar ;Ee адрес
mov DI,BX ;ES:DI -> начало строки
repe cmpsb ;Сравнение
je gotit ;Нашли нашу переменную

;Эта переменная в окружении не совпадает с нашей. Будем искать

;следующую. Сначала найдем 0, т.е. конец строки вида переменная=значение

tstnul: cmp byte ptr ES:[BX],0 ;Это 0?
je gotnul ;Нашли 0
inc BX ;Это не 0, на следующий байт
jmp tstnul ;Повторим анализ на 0

;Посмотрим, нет ли после этого 0 второго 0 – конца всего окружения

gotnul: inc BX ;К следующему байту
cmp byte ptr ES:[BX],0 ;Это 0?
jne compr ;Нет, на сравнение следующей

переменной

;Нашли второй 0 - конец окружения

;Выведем сообщение mes4 об отсутствии в окружении переменной WORKFILE.

;Можно также установить соответствующий код завершения в переменной errcode

...

gotit:

;Извлечем значение нашей переменной (т.е. имя файла) из окружения.

;DI -> первый байт значения переменной. Сначала определим

;длину значения переменной (оно заканчивается 0)

mov ВХ,-1 ;Счетчик длины, его начальное значение = 0
notend: inc ВХ  
cmp byte ptr ES:[DI][BX],0 ;Еще не 0?
jne notend ;Нет еще, продолжим поиск 0

;Нашли 0. ВХ = длина значения переменной.

;DI -> по-прежнему первый байт значения переменной.

;ES -> сегмент окружения.

;DS -> сегмент данных. Перенесем значение переменной (имя файла) в программу

mov CX,BX ;Число байт в имени файла
push ES ;Взаимно поменяем
push DS ;содержимое
pop ES ;сегментных
pop DS ;регистров
mov SI,DI ;DS:SI-> имя файла в окружении
mov Dl,offset ESitname ;ES:DI -> место для имени файла в программе
rep movsb ;Пересылка подстроки
push ES ;Восстановим адресацию
pop DS ;к нашим данным через DS

;Сделаем попытку открыть файл

...

jnc ok                   ;Переход, если СF = 0

;Обработаем ошибку открытия файла как и в предыдущих примерах

...

jmp outprog

;Завершим дочерний процесс

;Сначала выведем сообщение mes3 о нормальной работе

ok: ...

;И завершим дочерний процесс с передачей родительскому кода завершения

outprog:

...

;Поля данных

mes1     db '*Д* Дочерний процесс запущен ',10,13

mes1len equ $-mesl

mes2     db '*Д* Файл не открылся! ',10,13

mes2len equ $-mes2

mes3     db '*Д* Файл открылся и child завершается',10,13

mes3len equ $-mes3

mes4     db '*Д* Переменная WORKFILE '

db 'не найдена в окружении',10,13

mes4len equ $-mes4

fname   db 80 dup (0)

errcode db 0

envvar db 'WORKFILE='

len         equ $-envvar

 


Поделиться:



Последнее изменение этой страницы: 2019-05-07; Просмотров: 235; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.153 с.)
Главная | Случайная страница | Обратная связь