Пример вызова | Возвращаемое значение |
... :=Fexpand( 'test.txt' ) | 'C:\TEST\TEST.TXT' |
... :=Fexpand( '..\DEMO\d.pas' ) | 'C:\DEMO\D.PAS' |
... :=Fexpand( '..\auto.bat ' ) | 'C:\AUTO.BAT' |
... :=Fexpand( '\LEX\out.txt ' ) | 'C:\LEX\OUR.TXT' |
... :=Fexpand( '\' ) | 'C:\' |
... :=Fexpand( '\\' ) | 'C:\\ |
... :=Fexpand( 'SUBDIR\' ) | 'C:\TEST\SUBDIR\' |
... :=Fexpand( 'A:\LEX\our.txt' ) |
Программа на рис. 16.11 показывает, как можно применить процедуру FSplit и функцию FExpand для написания заведомо «капризных» программ, которые работают только с файлами из текущего каталога.
| USES DOS; { ПРИМЕР ОБРАБОТКИ ИМЕН ФАЙЛОВ }
| VAR X, FullName : PathStr; Dir : DirStr ;
| Name : NameStr; Ext : ExtStr ;
| BEGIN
| Write( 'Введите полное имя обрабатываемого файла: ' );
| ReadLn( X );
| FSplit(X, Dir, Name, Ext); { состав введенного имени }
| X:=FExpand( X ); { перевод в верхний регистр }
| if ( Dir=' ' ) or {He введен путь или же ка- }
| (X<>FExpand(Name+Ext)) { талог при X - не текущий. }
| then begin { Файл не оттуда! Конец. }
| WriteLn( #10'Ошибка в имени'+
| или попытка обмануть программу!' );
| Halt end; { if }
| ... { работа с верным именем }
| END.
Рис. 16.11
- 369 -
Не следует забывать, что параметры и переменные, стоящие в вызовах этих процедур, должны быть описаны соответствующими типами, хотя после вызовов с ними можно обращаться, как с обычными строками назначенной длины.
16.5. Работа с прерываниями MS-DOS
Вызов системных функций MS-DOS реализован в виде прерываний. Каждое прерывание, будучи активизированным, может открывать доступ к множеству различных функций. Так, например, прерывание с номером 16H дает доступ к функциям опроса клавиатуры на уровне операционной системы, прерывание с номером 25H управляет чтением диска и т.д. Особую роль играет прерывание с номером 21H. Оно открывает доступ к нескольким десяткам функций, образующим собственно операционную систему.
Работая на ассемблере, программист при необходимости вызова той или иной функции MS-DOS должен предварительно загрузить в определенные регистры процессора номер функции и ее аргументы и вызвать прерывание по его номеру. Список прерываний, связанных с ними функций и их аргументов, занял бы целую книгу и здесь не приводится. Заинтересованных мы отсылаем к техническим описаниям MS-DOS конкретных версий и БСВВ (BIOS) конкретных ПЭВМ.
А как быть тем, кто знает Паскаль, но не знаком с машинным кодом? Ответ прост: пользоваться процедурами модуля DOS, поддерживающими обращение к функциям MS-DOS (или прерываниям), прямо из Паскаль-программ (но знать, что делает прерывание и как выполняется, конечно, необходимо). Список этих процедур приводится в табл. 16.6.
Таблица 16.6
Процедура | Действие |
GetIntVec(N : Byte; VAR Adress : Pointer) | Возвращает в Adress адрес подпрограммы прерывания с заданным номером N |
SetIntVec(N : Byte; Adress : Pointer) | Устанавливает в DOS новую подпрограмму прерывания с номером N, замещая старое значение адреса на Adress |
- 370 -
Intr(N : Byte; VAR R : registers) | Активизирует программное прерывание N, передавая ему номер функции и параметры в переменной R |
MsDos(VAR R : Registers) | Специализированный вызов прерывания с номером 21H |
В таблице введен новый тип Registers. Он определен в модуле DOS и является записью с вариантами:
| TYPE
Registers = RECORD
case Integer of
0: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Word);
1:(AL, AH, BL, BH, CL, CH, DL, DH : Byte);
| END;
Переменные такого типа служат для доступа к регистрам микропроцессора при вызовах Intr и MsDos. Вариант 0 позволяет обращаться к 16-разрядным регистрам (парам), а вариант 1 — к 8-разрядным ячейкам процессора. Специально об указании варианта заботиться не следует. Если написать, например,
USES DOS;
VAR
R1, R2 : Registers;
BEGIN
R1.AX := $01FF;
R2.AL := $CA;
…
END.