Выполнение команд и программ

5.2.5. Выполнение команд и программ

 

Если Вы садитесь за ПЭВМ для производства определенных работ, то Вам потребуется выполнять команды DOS и программы под управлением системы. Запросы на их выполнение вводятся с клавиатуры в ответ на приглашение DOS и называются командными строками. Длина командной строки не должна превышать 127 символов. В дальнейшем мы увидим, что после­довательность командных строк может быть размещена в командном файле и выполнена из Него. Командная строка состоит из имени команды или спецификации исполняемого файла и, при необходимости, аргументов, разделенных по крайней мере одним пробелом. Возможно также задание переключателей, начинающихся символом /. Командная строка набирается на клавиатуре, как на обычной пишущей машинке, и отображается на экране дисплея. Сигнал от каждой нажатой пользователем клавиши, обрабатывается DOS, но КП никаких действий не предпринимает до обнаружения окончания командной строки. Сигналом об окончании командной строки служит нажатие клавиши Enter — только тогда командная строка считается введенной. До этого момента командную строку можно редактировать и аннулировать.

В общем случае под вводом символа или последовательности символов с клавиатуры будем понимать их печатание и последующее нажатие клавиши Enter.

Пример командной строки: DIR А:, что означает запрос на выдачу содержимого текущего каталога диска в приводе А.

Введенная командная строка анализируется КП, и дальнейшие его действия зависят от того, что требуется выполнить: внутреннюю команду, либо внешнюю команду или программу, либо командный, файл.

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

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

 

C>ERUNDA    Enter

Bad command or file name

(Ошибочная команда или ошибочное имя файла)

С>

 

В скобки    и  ► заключено наименование клавиши, которую следует нажать.

Если в спецификации подлежащего выполнению файла расширение в командной строке не задано, а в выделенном каталоге содержится несколько исполняемых файлов с указанными именами, но с различными расширениями, то возникший конфликт разрешается на основании приоритетов расширений. В DOS принято, что СОМ - файлы пользуются преимуществом перед другими (ЕХЕ- и ВАТ- файлами), а ЕХЕ - файлы — только перед ВАТ - файлами. Поэтому выбор файла для использования осуществляется однозначно в любом случае. При явном указании расширения коллизии не возникает.

Предположим, что по спецификации файла найден и выделен для выполнения СОМ- или ЕХ Е -файл (обработку ВАТ-файлов рассмотрим позже). В этом случае управление получает за­грузчик программ, содержащийся в транзитном модуле КП. Он выполняет следующие действия:

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

2} помещает полную спецификацию исполняемого файла (даже если его поиск проводился в разных каталогах) за дубликатом окружения DOS;

3) выделяет в ОЗУ область памяти для подлежащей выполнению программы, еще не занятую резидентной частью DOS и резидентными программами (отводится вся свободная память);

4) в начале этой области (с минимальными адресами) резервирует память под префикс программного сегмента (PSP Program Segment Prefix), который служит для хранения важной для выполняемой программы информации;

5) заполняет поля PSP следующими сведениями:

— объемом памяти, доступным для программы;

— адресом дубликата окружения DOS;

— аргументами из командной строки в символьном виде, которые благодаря этому становятся доступными программе;

— текущими векторами прерываний 22Н — 24Н для их восстановления при завершении выполнения программы и возврата в DOS;

6) загружает программу в ОЗУ за PSP.

 Затем, если в память переписана ЕХЕ - программа, то загрузчик по информации из ее заголовка осуществляет настройку этой программы в соответствии с точкой загрузки, т.е. перемещение программы.

Для СОМ - программы никакой настройки не требуется. Любая программа длиной менее 64 Кбайт и не содержащая никаких других сегментов, кроме программного, может быть таковой. Однако СОМ-программа способна иметь и большую длину, если в ней не используются явные ссылки к другим сегментам. При этом допустимы относительные ссылки с использованием точки загрузки как базового адреса. СОМ - программы загружаются быстрее и требуют меньшего объема внешней памяти для своего хранения.

После загрузки программы и возможного ее перемещения загрузчик передает управление (посредством дальнего JMP'a) на начало программы и она начинает выполняться.

КП имеет специальную область, называемую окружением DOS (точнее — корневым окруже­нием, так как при порождении процесса оно дублируется и, возможно, в измененном виде передается новому процессу, при его окончании дубликат окружения уничтожается, а оригинал окружения активизируется). Окружение хранит имена глобальных переменных и их значения в символьном виде, которые могут использоваться для получения определенной информации любыми выполняемыми под управлением DOS программами. Например, по значению опреде­ленной uлобальной переменной выполняемая программа может установить, в каком каталоге содержатся необходимые для ее (заботы файлы, либо как «вести себя» в том или ином случае. Пользователь может, используя средства командного языка, прочитать окружение, добавить в него новую запись вида «имя глобальной переменной - значение», обновить или удалить любую такую запись. Эти операции доступны выполняющимся программам. Как уже отмечалось, дочерняя программа получает от родительской программы статическую копию ее окружения, снабженную полной спецификацией файла, содержащего дочернюю программу. Этот факт используют «умные» программы для вычленения имени привода и выделенного маршрута при своем запуске для доступа к другим файлам, задействуемым этими программами и находящимся в одних с ними каталогах или каким-либо образом связанных с последними. Даже если исполняемый файл при запуске программы ищется в нескольких каталогах по маршрутам, определенным в системе, то все равно к дубликату окружения дописывается имя того привода и маршрут, где файл найден, а также его составное имя. Любые изменения, сделанные в окружении выполняемой программой, отменяются при ее завершении (так как любая программа работает с дубликатом окружения).

Для обмена информацией между ОЗУ и ПУ выполняемая программа может использовать средства файловой системы DOS (см. п. 5.2.2) или непосредственно обращаться к, ПВВ. При возникновении какой-либо ошибки в ПУ система пытается повторить операцию обмена 3 — 5 раз. Когда ошибку устранить не удалось, возникает прерывание 24Н, и DOS выдает на экран идентифицирующее ошибку сообщение, предлагает пользователю решить, что делать в этом случае, и ждет от него ответа. Например, если программа обращается к дисководу А для чтения информации, а он не готов к обмену (открыта защелка), то появятся следующие сообщения:

 

Not ready error reading drive a:

(Ошибка чтения из-за неготовности привода А:)

Abort, Retry, Fail  ? _

(Прервать, Повторить, Пропустить?)

 

На запрос пользователь может дать один из трех вариантов ответа, нажав клавишу А (для Abort), R (для Retry) или F (для Fail). В зависимости от варианта ответа, DOS реагирует на возникшую ошибку по-разному:

А     аномально завершает выполнение программы, выдавшей запрос на ввод-вывод;

R     повторяет операцию ввода-вывода;

F завершает выполнение операции и возвращает программе   соответствующий код ошибки;

 программа при этом продолжает выполняться.

Использовать ответ А нужно с осторожностью: Вы можете испортить большую часть выпол­ненной Вами работы по диалогу с интерактивной программой. Ответ R имеет смысл вводить, когда Вы устранили причину ошибки. Так, для рассмотренного примера достаточно запереть дисковод А: и нажать клавишу R. Ответ F может использоваться программой для анализа кода ошибки и выполнения определенных действий по ее нейтрализации, например, путем организации вводах другого дисковода, о чем пользователь должен быть извещен, чтобы переставить диск в новый привод (такая стратегия удобна, когда задействуемый накопитель неисправен).

Часто DOS выдает расширенный запрос

 

Abort, Ignore, Retry, Fail ?_ ,

 

где ответ I (для Ignore проигнорировать) означает продолжение операции ввода-вывода, как будто бы ничего не случилось. Такой ответ может привести к потере данных.

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

В программе можно предусмотреть свою реакцию на критическую ошибку, подменив вектор прерывания 24Н.

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

Любая программа в ходе своего выполнения может породить дочерний процесс, код которого находится в ЕХЕ- или СОМ - файле. Для этого она должна вызвать функцию 4ВН (EXEC) по прерыванию 21Н. В качестве аргументов порожденному процессу передается командная строка его запуска, текущее или модифицированное текущее окружение DOS (дубликат!), а также другая информация. Можно таким образом инициировать и вторичную копию КП для выполнения внутренней команды DOS. Порожденный процесс запускается и выполняется, как описано выше, а породившая его программа ждет его окончания. После завершения процесса родительская программа возобновляет активность.

Используя ту же функцию DOS 4ВН, можно не только породить процесс, но и просто загрузить программу в ОЗУ, не передавая ей управления. Это полезно при разработке оверлейных (загружающихся по частям с целью экономии памяти) программ. Больше никакой поддержки оверлейных программ DOS не обеспечивает. Все заботы по управлению оверлеями ложатся на плечи программиста или перекладываются на систему программирования.

Любая программа возвращает управление родительской программе по функции 4СН преры­вания 21Н. Если родительской программой является КП, то дополнительно инициируется пре­рывание 22Н, при обработке которого выполняются следующие действия:

1) аварийно закрываются все незакрытые в программе файлы, причём информация о файлах в каталогах не обновляется, так что созданные и обновленные программой файлы будут закрыты некорректно, а это приведет к потере информации и образованию на диске «мусора»; поэтому файлы всегда необходимо закрывать в программе явно;

2) освобождается вся память, использованная программой, в том числе и динамически;

3) из соответствующих полей PSP восстанавливаются векторы 22Н — 24Н, которые могли быть подменены программой.

Пользовательская программа не должна выдавать прерывание 22Н (это прерогатива системы).

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

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

Преждевременно завершить выполнение программы пользователь может путем нажатия кла­виш Ctrl-Break (УПР-ФСД СТОП). Однако сказанное справедливо только, если программа не подменила вектор прерывания 23Н. В противном случае реакция на нажатие этих клавиш будет определяться новым обработчиком данного прерывания. Сама возможность реакции на преры­вание 23Н определяется в файле CONFIG.SYS.

Если обработка прерывания по Ctrl-Break разрешена, то оно действует всегда, кроме тех моментов, когда реализуются функции DOS 06Н и 07Н (по прерыванию 21Н). В противном случае (если обработка Ctrl-Break запрещена) Ctrl-Break действует только во время обмена информацией с посимвольными устройствами.

Важно отметить, что:

1) нажатие Ctrl-Break приводит к установке по прерыванию 1ВН соответствующего флага в компьютере, но немедленная реакция на это отсутствует;

2) состояние указанного флага может проверяться (если обработка Ctrl-Break разрешена) только при вызове функции DOS;

3) прерывание 23Н возникает только в указанной в п. 2 ситуации.

Аналогом Ctrl-Break в DOS является комбинация клавиш Ctrl-C. Однако Ctrl-Break сильнее Ctrl-C, так как приводит практически к немедленному возникновению аппаратного прерывания 1ВН для установки флага. В отличие от этого код Ctrl-C вводится обычными средствами через буфер клавиатуры и обрабатывается DOS с тем, чтобы проимитировать нажатие Ctrl-Break. Если же чтение из буфера клавиатуры системой в данной ситуации не осуществляется, то нажатие Ctrl-C останется незамеченным и поэтому ни к каким изменениям в работе программы не приведет.

После окончания выполнения программы она может оставить себя резидентной в ОЗУ, вызвав функцию 31Н по прерыванию 21Н. При этом управление возвращается родительскому процессу (в частности DOS), но память, занятая программой, не освобождается. Вызываться на выполнение такая программа может впоследствии при возникновении прерываний, векторы которых она подменила. Такая техника используется в резидентных сервисных системах, а также при разработке программ, выполняющих роль драйверов устройств. Остающиеся резидентными программы обозначаются через TSR (Terminate but Stay Resident — завершиться, но остаться резидентной).

После окончания выполнения программы любым из перечисленных способов (если она была запущена КП, а не другой программой) на экране дисплея появляется подсказка DOS. Это и является внешним признаком завершения выполнения всех программ и ожидания DOS новой работы.

Выполняемая программа; особенно большого размера, может перекрывать в ОЗУ транзитный модуль КП, Резидентный модуль последнего, вслед за выходом из выполненной программы, распознает эту ситуацию путем подсчета контрольной суммы содержимого области памяти, в которой должен находиться транзитный модуль КП. Если результат не совпадает с эталоном, 'то резидентный модуль КП осуществляет загрузку с системного диска своей транзитной части.

Такая схема приводит к трудностям работы на ПЭВМ, не оборудованной жестким диском. Если пользователь во время выполнения какой-либо программы заменил системный диск на другой, требуемый для этой программы, то после завершения ее выполнения он скорее всего получит на экране сообщение

 

Insert disk with COMMAND.COM in drive a:

Press any key to continue ...

(Установите диск с COMMAND.COM'om в привод А.

Нажмите любую клавишу для продолжения)

 

До тех пор, пока пользователь не выполнит это предписание, работа на ПЭВМ не может быть продолжена. Облегчить работу путем исключения необходимости установки системного диска в привод А после выполнения программ можно одним из двух способов:

1) в корневой каталог каждой используемой дискеты записать файл COMMAND.CCJ.M;

2) при загрузке DOS создать виртуальный диск, скопировать на него файл COMMAND.COM и определить полную спецификацию копии этого файла в качестве значения глобальной пере­менной COMSPEC в окружении DOS (по умолчанию это значение указывает на системный диск).

Применение первого способа ведет к неэкономному использованию дисковой памяти, а второго — ОЗУ.

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