Тем не менее полученные числа для размеров стека и кучи вполне можно взять за начальные приближения. Если же они окажутся малы, то возникнут ошибки времени выполнения: 202 — переполнение стека и 203 — переполнение кучи (при отладке программ рекомендуем включать в них директиву проверки переполнения стека {$S+}).
Пусть, к примеру, вычисленные предварительно размеры стека и кучи будут равны 968 байт и 2000 байт соответственно. Тогда директива $М может иметь вид
{$М 1024, 0, 2048 -
Значения округлены в большую сторону до целого числа килобайтов. Вместо 0 можно, в принципе, поставить любое число, не превышающее максимальное значение кучи (здесь до 2048).
Программа, не имеющая вызовов New или GetMem внутри себя и во внешних библиотеках, подключаемых через директиву USES, кучи не использует, и может иметь директиву типа
{$М 4096, 0, 0 -
Установив директиву использования памяти, можно далее применять специальные процедуры (табл. 16.7) для организации субпроцессов и резидентных программ.
- 379 -
Процедуры | Назначение |
SwapVectors | Восстанавливает системные либо временные векторы прерываний для запускаемых субпроцессов |
Exec(ExeFile, ComLine : String) | Запускает выполнимый файл ExeFile (субпроцесс) со строкой параметров ComLine |
Функция DosExitCode : Word | Возвращает код завершения субпроцесса |
Keep(ExitCode : Word) | Завершение программы без стирания ее из памяти ПЭВМ (организация резидентного кода) |
16.6.1. Программирование субпроцессов
16.6.1.1. Процедура SwapVectors. При запуске среды Турбо Паскаль или созданного в ней выполнимого файла первым делом происходит смена ряда системных векторов прерываний на векторы отладчика среды и системной библиотеки. Однако адреса системных векторов не теряются, а запоминаются в переменных типа Pointer с именами SaveIntNN, где NN — номер прерывания (эти переменные являются предопределенными и привносятся вместе с системной библиотекой).
Пока программа работает сама по себе, нет особой необходимости восстанавливать системные векторы. Но если в программе организуется запуск субпроцесса, то будет разумнее, если он будет использовать именно системные векторы прерываний, а не специальные.
Процедура SwapVectors восстанавливает векторы прерываний, которые сохранены в переменных SaveIntNN, записывая одновременно в эти же переменные предыдущие векторы. Поэтому второй вызов SwapVectors вновь восстановит «отключенные» процедуры прерываний и сохранит в переменных последние активные адреса. Вообще говоря, можно даже взять за правило, чтобы в текстах программ соблюдалось требование четности вызовов процедуры SwapVectors.
Обычно эта процедура используется как «обрамляющая» для вызова Exec и в тех случаях, когда надо вернуться на время к исходным векторам, т.е. к тем, что были до запуска программы. О
- 380 -
номерах сохраняемых прерываний можно справиться в интерактивной подсказке среды программирования по модулю System.
16.6.1.2. Процедура Ехес( ExeFile, ComLine : String ). Эта процедура служит для запуска субпроцесса. Программа, в которой используются вызовы процедуры Exec, должна иметь в своем начале директиву распределения памяти {$М...}. Кроме того, рекомендуется до вызова Exec и сразу после него вставлять процедуру SwapVectors.
В процедуру передается два строковых аргумента: ExeFile — имя файла или полное имя файла (в обоих случаях обязательно указывать расширение имени) — это просто имя того файла, который нужно «запустить» из программы; ComLine — строка из аргументов, которые передаются запускаемому файлу.
Рассмотрим пример. Пусть в командной строке MS-DOS дается команда
С:\> format a: /s
Для подачи такой же команды из файла, т.е. организации субпроцесса форматирования, надо использовать команду Exec:
Ехес( 'format.com', 'a: /s' );
или даже
Ехес( 'c:\dos\format.com', 'a: /s' );
если файл format.com лежит не в текущем каталоге, а в C:\DOS.
Строка ComLine может быть и пустой. Это означает, что в запускаемую программу не передаются никакие параметры. Имя запускаемого файла всегда должно присутствовать.
Второй пример: в строке MS-DOS слияние файлов задается командой
С:\> copy a.txt + b.txt c.txt
Но COPY — встроенная команда командного процессора и не является запускаемым файлом. Чтобы реализовать ее как субпроцесс, необходимо запускать командный процессор COMMAND.COM и передавать ему текст команды в виде параметров:
Ехес( 'connmand.com', '/с copy a.txt+b.txt c.txt' );