11.1. ВНЕШНИЕ ПРОЦЕДУРЫ (Функции)
11.2. ИСПОЛЬЗОВАНИЕ ВСТРОЕННЫХ МАШИННЫХ КОДОВ
11.3. ОБРАЩЕНИЕ К ФУНКЦИЯМ ОПЕРАЦИОННОЙ СИСТЕМЫ
11.4. ПОДДЕРЖКА
ПРОЦЕДУР ОБРАБОТКИ ПРЕРЫВАНИЙ
При написании процедур
обработки прерываний существенными
являются два обстоятельства. Во-первых,
процедура обработки прерывания не должна
искажать работу прерванной программы.
Для этого необходимо сначала сохранить
регистры центрального процессора, а
перед выходом из процедуры - восстановить
их. Во-вторых, процедура должна строиться
по принципу реентерабельности (повторной
входимости): ее работа может быть
прервана в любой момент другими
прерываниями и ДОС может обратиться к
соответствующей функции до завершения
обработки предыдущего прерывания.
Турбо Паскаль предоставляет
программисту возможность написания
процедур обработки прерывания на языке
высокого уровня, хотя обычно такие
процедуры пишутся на языке ассемблера.
Процедура обработки прерывания,
написанная на Турбо Паскале, должна
начинаться стандартной директивой INTERRUPT (прерывание):
например:
Procedure IntProc (Flags,
CS, IP, AX, BX, CX, OX,
SI, OF. OS, ES, BP : word);
Inerrupt;
begin
end;
Формальные параметры
в заголовке процедуры должны
перечисляться в указанном порядке - через
эти параметры все регистры прерванной
программы становятся доступны процедуре
обработки прерывания. Количество
перечисляемых в заголовке процедуры
параметров-регистров может быть любым, но
не больше 12. Если в списке опущен какой-либо
параметр, должны быть опущены также и все
предшествующие ему параметры. Например,
описание
Procedure intProc(S), DP, ES: word); Interrupt:
будет неверным (опущены параметры DS и ВР);
правильное описание:
Procedure lntProc(Sl, OP, DS, ES, BP: word); Interrupt;
Заметим, что компилятор не контролирует
порядок перечисления параметров в
заголовке процедуры обработки
прерывания.
Директива INTERRUT вызывает генерацию
специальных машинных кодов,
обеспечивающих сталкивание регистров в
стек при входе в процедуру и извлечение
их из стека перед выходом из нее.
При входе в процедуру:
push ax
push bх
push ex
push dx
push si
push di
push ds
push es
push bp
mov bp, si
sub sp, LocalSIze
mov ax, SEG DATA
mov ds, ax
При выходе из процедуры:
mov sp, bp
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop ex
pop bx
pop ax
Irep
В самой процедуре обработки
прерывания не рекомендуется обращаться к
другим функциям ДОС, так как некоторые из
них, в том числе все функции ввода-вывода,
нереентерабельны.
Для связи с любыми процедурами
прерываний, а следовательно, и с
процедурами, написанными программистом,
используются векторы прерываний -
четырехбайтные абсолютные адреса точек
входа в эти процедуры. Векторы прерываний
располагаются в младших адресах
оперативной памяти, начиная с нулевого
адреса: прерывание номер 0 - по адресу О,
номер 1 - по адресу 1*4-4, номер N - по адресу N *
4. С помощью следующих двух процедур
программист может прочитать содержимое
любого вектора или установить его новое
значение.
Процедура GETINTVEC.
Возвращает вектор прерывания с указанным
номером.
Обращение:
GETINTVEC (<N>,<векmop>)
Здесь <N> - выражение типа BYTE; номер
прерывания; <вектор> - переменная типа
POINTER; адрес точки входа в процедуру
обработки прерывания. Представленная в
примере 22 программа выводит на экран
содержимое всех ненулевых векторов
прерываний.
Пример 22.
Uses DOS;
var
i : byte;
p : pointer;
BEGIN
for i := 0 to 255 do
begin
GetlntVec (i, p);
if (Seg (р^)<> 0) or (Ofs (р^) <> 0) then
writeln (' N =', 1:3. ' Seg =', Seg (р^):5,
‘Ofs =', Ofs (ð^):5)
end
END.
Процедура SETINTVEC. Устанавливает новое
значение вектора прерывания. Формат
обращения:
SETINTVEC (<N>,<adpec>)
Здесь <N> - выражение типа BYTE; номер
прерывания;
<адрес> - выражение типа POINTER; адрес
точки входа в процедуру обработки
прерывания.
При нормальном завершении программы она
выгружается из памяти, что делает
невозможным разработку резидентных в
памяти процедур обработки прерываний. Вы
можете прекратить работу программы и
оставить ее резидентной в памяти, если
воспользуетесь процедурой KEEP.
Процедура KEEP. Завершает работу программы
и оставляет ее резидентной в памяти.
Обращение:
KEEP (<код>)
Здесь <код> - выражение типа WORD - код
завершения программы. Код завершения
представляет собой фактически
единственный механизм передачи
сообщений от запущенной программы к
программе, которая ее запустила. Он может
быть проанализирован в вызывающей
программе с помощью функции DOSEXITCODE.
Функция DOSEXITCODE. Возвращает значение типа
WORD – êîä çàâåðøåíèÿ ïîä÷èíåííîé
программы.
Обращение:
DOSEX1TCODE
11.5. ЗАПУСК ВНЕШНИХ ПРОГРАММ
Из программы, написанной на Турбо
Паскале, можно запустить любую другую
готовую к работе программу. Для этого
используется процедура ЕХЕС из
библиотечного модуля DOS. Формат обращения
к процедуре:
ЕХЕС (<имя>,<параметры>)
Здесь <имя> - выражение типа STRING; имя
файла с вызываемой программой;
<параметры> - выражение типа STRING;
параметры вызова.
Имени запускаемой программы может
предшествовать путь к файлу. Параметры
передаются запускаемой программе в виде
текстовой строки и могут быть
проанализированы ею с помощью двух
следующих функций.
Функция PARAMCOUNT. Возвращает общее
количество параметров вызова программы (значение
типа WORD). Обращение: PARAMCOUNT
Параметры вызова обычно следуют в
командной строке ДОС сразу за именем
вызываемой программы и отделяются от
этого имени и друг от друга пробелами,
например:
C:\>TURBO MYPROG.PAS
C:\>S1AM A:\SYSTEM1.SIA
Здесь MYPROG.PAS и A:\SYSTEMJ.SJA - параметры,
передаваемые программам TURBO и SIAM.
При вызове программы непосредственно из
среды Турбо Паскаля ей можно передать
параметры с помощью опции OPTIONS/PARAMETERS (см.
прил.1).
Функция PARAMSTR. Возвращает значение типа
STRING, соответствующее нужному параметру
вызова. Формат обращения: PARAMSTR (<N>)
Здесь <N> - выражение типа WORD;
порядковый номер параметра.
Заметим, что программе всегда передается
параметр, соответствующий N = 0. В этом
параметре ДОС сообщает полное имя
запущенной программы с указанием диска и
каталога, откуда она была загружена.
Использование процедуры ЕХЕС имеет ряд
особенностей. Прежде всего необходимо
отметить, что сама вызывающая программа
остается резидентной в памяти, поэтому
она не должна занимать всю оперативную
память. Объем выделяемой программе
памяти регулируется опцией OPTIONS/MEMORY SIZE (см.
прил.1). По умолчанию параметры LOW HEAP LIMIT и
HIGH HE АР LIMIT этой опции таковы (соответственно
0 и 655360 байт), что вызывающая программа,
написанная на Турбо Паскале, занимает
весь доступный объем памяти, и вызываемая
программа не будет загружена. Полезно
включить в текст вызывающей программы
директиву компилятора, в которой
изменяются принятые по умолчанию размеры
памяти. Например, так:
{$M 2048, 0, 0}
Такая директива ограничивает
используемую программой область стека
величиной 2 Кбайта и исключает
возможность использования в ней
динамической памяти. Разумеется, Вы
можете установить и другие знания
параметров в этой директиве.
Специфические особенности исполнения
Турбо Паскалевых программ требуют
изменения стандартных значений
некоторых векторов прерываний. К ним
относятся векторы со следующими
шестнадцатиричными номерами:
$00, $02, $18, $23, $24, $34, $35, $36, $37,
$38, $39, $ЗА, $ЗВ, $ЗС, $3D, $3E, $3F, $75.
Начальные значения этих
векторов сохраняются в восемнадцати (переменных
с именами SAVEINTXX из библиотечного модуля
SYSTEM, где XX - шестнадцатиричный номер
прерывания. Поэтому непосредстнно перед
запуском внешней программы и сразу после
возврата из нее рекомендуется вызывать
библиотечную процедуру без параметров
WAPVECTORS, которая обменивает содержимое
векторов прерывания перечисленных
переменных.
Программа примера 23 читает с клавиатуры
любую команду ДОС, затем вызывает
командный процессор COMMAND.COM операционной
системы и передает ему эту команду.
Обратите внимание: для указания файла
COMMAND.COM и пути к нему используется
обращение к библиотечной функции GETENV, с
помощью которой можно получить параметры
настройки операционной системы. В
частности, параметр COMSPEC определяет
спецификацию файла, содержащего
командный процессор.
П р и м е р 23.
{$М 1024, 0, 0}
Uses DOS:
var
st : string[79];
BEGIN
write ('Введите команду ДОС: '); readln (st);
if st <> " then
begi n
st := '/C '+st:
SwapVectors;
Exec (GetEnv (‘COMSPEC’), st);
SwapVectors
End
END.
Функция ENVCOUNT. Возвращает значение типа
INTEGER, в котором содержится общее
количество установленных в ДОС
параметров.
Обращение:
ENVCOUNT
Функция ENVSTR. Возвращает значение типа STRING,
содержащее имя и значение нужного
параметра настройки операционной
системы. Формат обращения:
ENVSTR (<N>)
Здесь <N> - выражение типа INTEGER; номер
параметра.
Эта функция возвращает строку типа NAME=VALUE,
где NAME -имя, a VALVE - значение
соответствующего параметра настройки.
Функция GETENV. Возвращает значение типа STRING,
в котором содержится параметр настройки
ДОС. Формат обращения: GETENV (<имя>)
Здесь <имя> - выражение типа STRING', имя
параметра.
Эта функция имеет параметр обращения NAME,
а возвращает значение VALVE (см. функцию ENVSTR).
11.6. ОВЕРЛЕЙ
11.7. ПРЯМОЕ ОБРАЩЕНИЕ К ПАМЯТИ И ПОРТАМ ВВОДА-ВЫВОДА
11.8. ВСТРОЕННЫЙ АССЕМБЛЕР