Компьютер - электронное устройство, которое не заменит человека до тех пор, пока не научится смеяться шуткам начальника и сваливать свои собственные ошибки на соседний компьютер.




а изменит содержимое управляющего блока, то цепочка будет разорвана и DOS начнет выдавать сообщения об ошибке.
      MS DOS обеспечивает три функции распределения памяти, номера от 48H до 4AH прерывания 21H. Функция 48H отводит блок памяти, а 49H - освобождает блок памяти. Третья функция ("SETBLOCK") ме- няет размер памяти, отведенной для программы; эта функция должна быть использована перед двумя остальными. После ее выполнения можно спокойно отводить и освобождать блоки памяти. Программа должна освободить все отведенные ею блоки перед завершением. Иначе эта память будет недоступной для последующего использова- ния.

      Средний уровень.

      Все три функции распределения памяти прерывания 21H используют 16-битный адрес начала блока памяти, с которым они оперируют. Этот адрес соответствует сегменту, с которого начинается блок (блок всегда начинается со смещения 0 данного сегмента). Таким образом реальный адрес ячейки начала блока равен этому адресу, умноженному на 16. Также, для всех трех функций, BX содержит число 16-байтных разделов памяти (параграфов), которые будут отводиться или освобождаться. Если функция не может быть выполне- на, то устанавливается флаг переноса, а в AX возвращается код ошибки, объясняющий причину. Возможны три кода ошибки:

      7 разрушен управляющий блок памяти
      8 недостаточно памяти для выполнения функции
      9 неверный адрес блока памяти
Функция отведения блока использует коды 7 и 8, а освобождения - 7 и 9, в то время как функция изменения блока использует все три кода. В следующем примере сначала отводится блок, размером 1024 байта. При этом BX содержит требуемое число 16-байтных парагра- фов, а при завершении стартовый адрес блока равен AX:0 (т.е. смещение 0 в сегменте со значением, содержащимся в AX). Вторая часть примера освобождает этот же блок, как и требуется при за- вершении программы. В данном случае значение полученное в AX помещается в ES. DOS следит за размером блока и знает какое коли- чество параграфов надо освободить.
;---отведение блока размером 1024 байта
      MOV AH,48H ;номер функции
      MOV BX,64 ;требуем 64 параграфа
      INT 21H ;пытаемся отвести блок
      JC ERROR ;обрабатываем ошибку в случае неудачи
      MOV BLOCK_SEG,AX;иначе сохраняем адрес блока
      . ;---освобождаем тот же блок
      MOV AX,BLOCK_SEG ;получаем стартовый адрес блока
      MOV ES,AX ;помещаем его в ES
      MOV AH,49H ;номер требуемой функции
      INT 21H ;освобождаем блок памяти


      Наконец, приведем пример использования функции 4AH. ES содер- жит значение сегмента PSP, т.е. самого первого байта памяти, с которого загружена программа. Это значение присваивается ES при старте задачи. Для использования SETBLOCK надо либо вызывать эту функцию в самом начале программы (прежде чем ES будет изменен), либо сохранить его начальное значение для последующего использо- вания.
      BX содержит требуемый размер блока в 16-байтных параграфах. Для определения этого размера поместите добавочный "искуственный" сегмент в конец программы. В макроасссемблере IBM PC сегменты располагаются в алфавитном порядке, поэтому Вы можете поместить его в любое место программы, при условии, что его имя это что-то вроде "ZSEG". В других ассемблерах действительно помещайте фик- тивный сегмент в конец программы. Программа может прочитать пози- цию этого сегмента и, сравнивая ее со стартовым сегментом, полу- чить количество памяти, требуемое самой программе. В момент заг- рузки программы и ES и DS содержат номер параграфа самого начала программы в префиксе программного сегмента; для COM файлов CS также указывает на эту позицию, но для EXE файлов это не так. ;---освобождение памяти (ES имеет значение при старте)
      MOV BX,ZSEG ;получаем # параграфа конца программы + 1
      MOV AX,ES ;получаем # параграфа начала программы
      SUB BX,AX ;вычисляем размер программы в параграфах
      MOV AH,4AH ;номер функции
      INT 21H ;освобождаем память
      JC MEMORY_ERROR ;проверяем на ошибку
;---
      ZSEG SEGMENT
      ZSEG ENDS


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 выделяет ей всю д