|
ДУБЛИКАТ ХЕНДЛА ( ФУНКЦИЯ 45Н )
Вызов: АН = 45Н
ВХ - хендл
Возвращает: CF установлен:
АХ - 4 = Слишком много
открытых файлов
6 = несуществующий
хендл
CF сброшен:
АХ - новый хендл
Комментарий:
Функция 45Н создает дополнительный хендл для файла. ВХ
должен содержать хендл открытого файла.
Система возвращает новый хендл в АХ. Новый хендл
относится к тому же файлу, что и хендл, загруженный в ВХ.
После выполнения этой функции, любое смещение указателя
файла в одном хендле вызывает такое же смещение указателя в
другом. Обычно эта функция используется для переадресовки
стандартного ввода (хендл 0) и стандартного вывода (хендл 1).
Подробное описание стандартных ввода и вывода, а также техники
их программирования смотрите в Software tools, авторы - Brian
W. Kernighan и P.J. Plauger (Addison-Wesley Publishing
Co.,1976).
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
4 Слишком много открытых файлов (нет больше хендлов)
6 Хендл не открыт или не существует
__________________________________________________________
Макроопределение:
xdup macro handle
mov bx,handle
mov ah,45H
int 21H
endm
Пример:
Следующая программа переадресовывает стандартный вывод
(хендл 1) файлу dirfile, вызывает вторую копию command.com для
листинга каталога ( и записи его в файл dirfile), а
затем восстанавливает стандартный вывод хендлу 1.
pgm-file db "command.com",0
cmd-line db 9,"/c dir /w",0DH
parm-blk db 14 dup (0)
path db "dirfile",0
dir-file dw ? ; Для хендла
sav-stdout dw ? ; Для хендла
;
begin: set-block last-inst ; См. функцию 4АН
jc error-setblk ; Метка не показана
- 119 -
create-handle path,0 ; См. функцию 3СН
jmp error-create ; Метка не показана
mov dir-file,ax ; Сохранить хендл
xdup 1 ; Наша функция
jc error-xdup ; Метка не показана
mov sav-stdout,ax ; Сохранить хендл
xdup2 dir-file,1 ; См. функцию 46Н
jc error-xdup2 ; Метка не показана
exec pgm-file,cmd-line,parm-blk ; Функция 4ВН
jc error-exec ; Метка не показана
xdup2 sav-stdout,1 ; См. функцию 46Н
jc error-xdup2 ; Метка не показана
close-handle sav-stdout ; См. функцию 3ЕН
jc error-close ; Метка не показана
close-handle dir-file ; См. функцию 3ЕН
jc error-close ; Метка не показана
АКТИВИЗИРОВАТЬ ДУБЛИКАТ ХЕНДЛА ( ФУНКЦИЯ 46Н )
Вызов: АН = 46Н
ВХ - хендл
СХ - второй хендл
Возвращает: CF установлен:
АХ - 4 = слишком много
открытых файлов
6 = несуществующий хендл
CF сброшен:
нет ошибок
Комментарий:
Функция 46Н ассоциирует указанный хендл с файлом в
качестве второго хендла, уже ассоциированного с открытым
файлом. ВХ должен содержать хендл открытого файла. СХ
содержит второй хендл.
После выполнения функции хендл, загруженный в СХ,
относится к тому же файлу, что и хендл из ВХ и с той же
позицией указателя. Если файл, к которому относится хендл из
СХ на момент вызова функции был открыт, то функция закрывает
его.
После выполнения этой функции, любое смещение указателя
файла в одном хендле вызывает такое же смещение указателя в
другом. Обычно эта функция используется для переадресовки
стандартного ввода (хендл 0) и стандартного вывода (хендл 1).
Подробное описание стандартных ввода и вывода, а также техники
их программирования смотрите в Software tools, авторы - Brian
W. Kernighan и P.J. Plauger (Addison-Wesley Publishing
Co.,1976).
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
4 Слишком много открытых файлов (нет больше хендлов)
6 Хендл не открыт или не существует
__________________________________________________________
- 120 -
Макроопределение:
xdup2 macro handle1,handle2
mov bx,handle1
mov cx,handle2
mov ah,46H
int 21H
endm
Пример:
Следующая программа переадресовывает стандартный вывод
(хендл 1) файлу dirfile, вызывает вторую копию command.com для
листинга каталога ( и записи его в файл dirfile), а
затем восстанавливает стандартный вывод хендлу 1.
pgm-file db "command.com",0
cmd-line db 9,"/c dir /w",0DH
parm-blk db 14 dup (0)
path db "dirfile",0
dir-file dw ? ; Для хендла
sav-stdout dw ? ; Для хендла
;
begin: set-block last-inst ; См. функцию 4АН
jc error-setblk ; Метка не показана
create-handle path,0 ; См. функцию 3СН
jmp error-create ; Метка не показана
mov dir-file,ax ; Сохранить хендл
xdup 1 ; См. функцию 45Н
jc error-xdup ; Метка не показана
mov sav-stdout,ax ; Сохранить хендл
xdup2 dir-file,1 ; Наша функция
jc error-xdup2 ; Метка не показана
exec pgm-file,cmd-line,parm-blk ; Функция 4ВН
jc error-exec ; Метка не показана
xdup2 sav-stdout,1 ; Наша функция
jc error-xdup2 ; Метка не показана
close-handle sav-stdout ; См. функцию 3ЕН
jc error-close ; Метка не показана
close-handle dir-file ; См. функцию 3ЕН
jc error-close ; Метка не показана
ПОЛУЧИТЬ ТЕКУЩИЙ КАТАЛОГ ( ФУНКЦИЯ 47Н )
Вызов: АН = 47Н
DL - номер дисковода
( 0=текущий, 1=А и т.д.)
DS:SI - указатель на 64-байтовый
участок памяти
Возвращает: CF установлен:
АХ - 15 = несуществующий
номер дисковода
CF сброшен:
нет ошибок
Комментарий:
Функция 47Н возвращает маршрут текущего каталога на
- 121 -
указанном дисководе. DL должен содержать номер дисковода, а SI
смещение (сегментный адрес в DS) 64-байтового участка памяти.
MS-DOS помещает в этот участок памяти строку ASCIZ,
содержащую (начиная от корневого каталога) маршрут текущего
каталога на дисководе, указанном в DL. Эта строка не может
начинаться с обратного слэша (наклонной) и не включает имя
дисковода.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
15 Содержимое DL не является разрешенным номером
дисковода
__________________________________________________________
Макроопределение:
get-dir macro drive,buffer
mov dl,drive
mov si,offset buffer
mov ah,47H
int 21H
endm
Пример:
Следующая программа выводит на экран текущий каталог
с дисковода В.
disk db "b:
buffer db 64 dup (?)
;
begin: get-dir 2,buffer ; Наша функция
jc error-dir ; Метка не показана
display disk ; См. функцию 09Н
display-asciz buffer ; См. конец главы
ВЫДЕЛИТЬ ПАМЯТЬ ( ФУНКЦИЯ 48Н )
Вызов: АН = 48Н
ВХ - запрашиваемая память в параграфах
Возвращает: CF (флаг переноса) установлен:
АХ - 7 = разрушены блоки
управления памятью
8 = мало памяти
ВХ - доступная память в
параграфах
CF сброшен:
АХ - сегментный адрес
выделенной памяти
Комментарий:
Функция 48Н выделяет указанный объем памяти текущей
программе. ВХ должен содержать объем требуемой памяти в
параграфах ( один параграф = 16 байт ).
Если имеется достаточный объем памяти для удовлетворения
запроса, то АХ возвращает сегментный адрес выделенной памяти
- 122 -
(смещение равно 0). Если памяти не достаточно, то ВХ
возвращает объем в параграфах наибольшего доступного участка.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
7 Разрушены блоки управления памятью ( программа
пользователя изменила содержание не принадлежащей
ей памяти)
8 Нет достаточного объема памяти для удовлетворения
запроса
__________________________________________________________
Макроопределение:
allocate-memory macro bytes
mov bx,bytes
mov cl,4
shr bx,cl
inc bx
mov ah,48H
int 21H
endm
Пример:
Следующая программа открывает файл textfile.asc,
вычисляет его размер с помощью функции 42Н (Сдвинуть указатель
файла), выделяет участок памяти, равный размеру файла, читает
в него этот файл, а затем освобождает выделенную память.
path db "textfile.asc",0
msg1 db "Файл загружен в выделенный участок памяти.",
0DH,0AH
msg2 db "Выделенная память освобождена.",0DH,0AH
handle dw ?
mem-seg dw ?
file-len dw ?
;
begin: open-handle path,0
jc error-open ; Метка не показана
mov handle,ax ; Сохранить хендл
move-ptr handle,0,0,2 ; См. функцию 42Н
jc error-move ; Метка не показана
mov file-len,ax ; Сохранить длину файла
set-block last-inst ; См. функцию 4АН
jc error-setblk ; Метка не показана
allocate-memory file-len ; Наша функция
jc error-alloc ; Метка не показана
mov mem-seg,ax ; Сохранить адрес
; новой памяти
move-ptr handle,0,0,0 ; См. функцию 42Н
jc error-move ; Метка не показана
push ds ; Сохранить DS
mov ax,mem-seg ; Взять сегментный
; адрес новой памяти
mov ds,ax ; и загрузить в DS
read-handle cs:handle,0,cs:file-len ; Читать
; файл в новую память
pop ds ; Восстановить DS
- 123 -
jc error-read ; Метка не показана
write-handle stdout,msg1,42 ; См. функцию 40Н
jc write-error ; Метка не показана
free-memory mem-seg ; См. функцию 49Н
jc error-freemem ; Метка не показана
write-handle stdout,msg2,30 ; См. функцию 40Н
jc write-error ; Метка не показана
ОСВОБОДИТЬ ВЫДЕЛЕННУЮ ПАМЯТЬ ( ФУНКЦИЯ 49Н )
Вызов: АН = 49Н
ES - сегментный адрес освобождаемой
памяти
Возвращает: CF установлен:
АХ - 7 = разрушены блоки
управления памятью
9 = неправильный сегмент
CF сброшен:
нет ошибок
Комментарий:
Функция 49Н освобождает (делает доступной) участок
памяти, выделенный ранее с помощью функции 48Н (Выделить
память). ES должен содержать сегментный адрес освобождаемого
участка памяти.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
7 Разрушены блоки управления памятью ( программа
пользователя изменила содержание не принадлежащей
ей памяти)
9 Участок памяти, адресуемый ES, не был до этого
выделен с помощью функции 48Н
__________________________________________________________
Макроопределение:
free-memory macro seg-addr
mov ax,seg-addr
mov es,ax
mov ah,49H
int 21H
endm
Пример:
Следующая программа открывает файл textfile.asc,
вычисляет его размер с помощью функции 42Н (Сдвинуть указатель
файла), выделяет участок памяти, равный размеру файла, читает
в него этот файл, а затем освобождает выделенную память.
path db "textfile.asc",0
msg1 db "Файл загружен в выделенный участок памяти.",
0DH,0AH
msg2 db "Выделенная память освобождена.",0DH,0AH
- 124 -
handle dw ?
mem-seg dw ?
file-len dw ?
;
begin: open-handle path,0
jc error-open ; Метка не показана
mov handle,ax ; Сохранить хендл
move-ptr handle,0,0,2 ; См. функцию 42Н
jc error-move ; Метка не показана
mov file-len,ax ; Сохранить длину файла
set-block last-inst ; См. функцию 4АН
jc error-setblk ; Метка не показана
allocate-memory file-len ; См. функцию 48Н
jc error-alloc ; Метка не показана
mov mem-seg,ax ; Сохранить адрес
; новой памяти
move-ptr handle,0,0,0 ; См. функцию 42Н
jc error-move ; Метка не показана
push ds ; Сохранить DS
mov ax,mem-seg ; Взять сегментный
; адрес новой памяти
mov ds,ax ; и загрузить в DS
read-handle cs:handle,0,cs:file-len ; Читать
; файл в новую память
pop ds ; Восстановить DS
jc error-read ; Метка не показана
write-handle stdout,msg1,42 ; См. функцию 40Н
jc write-error ; Метка не показана
free-memory mem-seg ; Наша функция
jc error-freemem ; Метка не показана
write-handle stdout,msg2,30 ; См. функцию 40Н
jc write-error ; Метка не показана
УСТАНОВИТЬ УЧАСТОК ( ФУНКЦИЯ 4АН )
Вызов: АН = 4АН
ВХ - параграфы памяти
ES - сегментный адрес участка памяти
Возвращает: CF (флаг переноса) установлен:
АХ - 7 = разрушены блоки
управления памятью
8 = мало памяти
9 = неправильный сегмент
ВХ - доступная память в
параграфах
CF сброшен:
нет ошибок
Комментарий:
Функция 4АН изменяет размер участка выделяемой памяти. ES
должен содержать сегментный адрес этого участка. В ВХ должен
быть загружен размер нового участка памяти в параграфах.
Если попытка изменить размер участка в ответ на запрос о
его увеличении не удалась, то ВХ возвращает максимальный
размер ( в параграфах ), до которого этот участок может быть
увеличен.
- 125 -
Так как MS-DOS выделяет всю имеющуюся память .com
программам, то вам не раз придется использовать эту функцию
для сужения участка начально выделяемой памяти.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
7 Разрушены блоки управления памятью ( программа
пользователя изменила содержание не принадлежащей
ей памяти)
8 Нет достаточного объема памяти для удовлетворения
запроса
9 Участок памяти, адресуемый ES, не может быть
модифицирован с помощью этой функции
__________________________________________________________
Нижеприведенное макроопределение сужает размер начально
выделяемой памяти .com программе. В качестве параметра берется
смещение первого байта, следующего за последним байтом кода
программы (в программах - примерах это last-inst), и
используется для вычисления размера программы в параграфах.
Затем к полученному результату добавляется 17: один для
выравнивания (округления) и 16 для отступа 256 байт,
предназначенных для стэка. После этого выставляются
соответствующим образом регистры SP и ВР, адресующие стэк.
Макроопределение:
set-block macro last-byte
mov bx,offset last-byte
mov cl,4
shr bx,cl
add bx,17
mov ah,4FH
int 21H
mov ax,bx
shl ax,cl
dec ax
mov sp,ax
mov bp,sp
endm
Пример:
Следующая программа вызывает вторую копию command.com и
выполняет команду DIR.
pgm-file db "command.com",0
cmd-line db 9,"/c dir /w",0DH
parm-blk db 14 dup (?)
reg-save db 10 dup (?)
;
begin: set-block last-inst ; Наша функция
exec pgm-file,cmd-line,parm-blk,0 ;
; См. функцию 4ВН
- 126 -
ЗАГРУЗИТЬ И ВЫПОЛНИТЬ ПРОГРАММУ ( ФУНКЦИЯ 4ВН, КОД 00Н )
Вызов: АН = 4ВН
AL = 00H
DS:DX - указатель на маршрут
ES:BX - указатель на блок параметров
Возвращает: CF установлен:
АХ - 1 = несуществующая функция
2 = файл не найден
3 = маршрут не найден
4 = слишком много открытых
файлов
5 = нет доступа
8 = мало памяти
10 = не та среда
11 = не тот формат
CF сброшен:
нет ошибок
Комментарий:
Функция 4ВН (код 00Н) загружает и выполняет программу. DX
должен содержать смещение (сегментный адрес в DS) строки
ASCIZ, указывающей дисковод и маршрут выполняемого
программного файла. В ВХ необходимо загрузить смещение
(сегментный адрес в ES) блока параметов, a в AL 0.
Для загрузки программного файла в памяти должно быть
достаточно места. MS-DOS выделяет всю имеющуюся память
программе при ее загрузке, поэтому вам необходимо освободить
часть памяти с помощью функции 4АН (Установить участок) перед
загрузкой и выполнением другой программы ( желательно сузить
участок, занимаемый текущей программой, по возможности, до
минимума).
MS-DOS создает для загружаемой программы Префикс сегмента
кодов (PSP) и устанавливает адреса процедур завершения и
CONTROL+C сразу после команды вызова функции 4ВН в вызывающей
программе.
Блок параметров состоит из 4 адресов:
Таблица 1.24
__________________________________________________________
Смещение Длина Описание
(байты)
__________________________________________________________
00Н 2 Сегментный адрес среды; 00Н значит копи-
рование среды родительской программы
02Н 4 Сегмент:смещение командной строки, поме-
щаемой в PSP со смещением 80Н. Должна
соответствовать соглашениям и не
превышать 128 байт
06Н 4 Сегмент:смещение блока управления файлом
(FCB), помещаемого в PSP со смещением 5СН
0АН 4 Сегмент:смещение FCB, помещаемого в PSP
со смещением 6СН
__________________________________________________________
Все открытые программой файлы доступны и вновь
загруженной программе, передавая родительской программе
контроль за определением стандартных ввода, вывода,
дополнительного устройства и принтера. Например, программа
- 127 -
может открыть файл в качестве стандартного ввода, открыть
второй файл в качестве стандартного вывода, затем загрузить,
используя функцию 4ВН (код 00Н), программу, которая берет
данные со стандартного ввода, сортирует записи, и записывает
на стандартный вывод.
Загружаемая программа получает также среду - серию строк
ASCIZ по форме параметр=значение (например, verify=on). Среда
должна начинаться на границе параграфа , не превышать 32
килобайта и заканчиваться байтом 00Н (таким образом, последняя
строка состоит из строки ASCIZ, заканчивающейся байтом 00Н,
и еще одного байта 00Н). После двух нулевых байтов идет ряд
начальных аргументов, передаваемый программе, и представляющий
собой счетчик, за которым следует строка ASCIZ. Если функция
находит файл в текущем каталоге, то строка ASCIZ содержит
дисковод и маршрут программного файла, передаваемые функции
при вызове. Если функция находит файл на маршруте, то она
связывает вместе имя файла и маршрут. ( Программа может
использовать эту область, чтобы определить, откуда она была
загружена.) Если адрес среды равен нулю, то загружаемая
программа либо наследует копию среды родительской программы,
либо получает среду, созданную для нее родительской программой.
Поместите сегментный адрес среды в PSP новой программы со
смещением 2СН. Среда для загружаемой программы должна
начинаться на границе параграфа. Если вы хотите создать ее для
новой программы, то ее сегментный адрес надо поместить и в
первое слово блока параметров. Если нужно просто передать
копию среды родительской программы это слово надо выставить в
ноль.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
1 AL не 0 и не 3
2 Программный файл не найден
3 Несуществующий маршрут
4 Слишком много открытых файлов
5 Каталог заполнен, каталог с таким же именем уже
существует, или файл с таким же именем уже
существует
8 Не хватает памяти для загрузки программы
10 Длина среды превышает 32 килобайта
11 Програмным файлом является .exe файл, содержащий
внутренне непостоянную информацию
__________________________________________________________
Загрузка второй копии Command.com
Самый простой способ загрузить и выполнить дочернюю
программу это загрузка и выполнение второй копии command.com.
Нужно лишь передать ей командную строку с переключателем /с,
который вызывает .com или .exe файлы.
Такая процедура требует 17 килобайт свободной памяти, и
программа, которая ее выполняет, должна обязательно сузить
объем первоначально выделенной ей памяти с помощью функции
4АН. Ниже приведен формат командной строки с переключателем /с:
длина, /С команда, 0DH , где:
длина - длина командной строки, включая байт длины и не
- 128 -
включая байт ВК (0DH).
команда - любая команда MS-DOS.
0DH - символ возврата каретки
Если программа загружает и выполняет другую программу
напрямую - передав ее в качестве програмного файла функции
4ВН, и не вызывая command.com - она должна выполнить все
обычно выполняемые command.com действия.
Макроопределение:
exec macro path,command,parms
mov dx,offset path
mov bx,offset parms
mov word ptr parms[02H],offset command
mov word ptr parms[04H],cs
mov word ptr parms[06H],5CH
mov word ptr parms[08H],es
mov word ptr parms[0AH],6CH
mov word ptr parms[0CH],es
mov al,0
mov ah,4BH
int 21H
endm
Пример:
Следующая программа вызывает вторую копию command.com и
выполняет команду DIR с опцией /w.
pgm-file db "command.com",0
cmd-line db 9,"/c dir /w",0DH
parm-blk db 14 dup (?)
reg-save db 10 dup (?)
;
begin: set-block last-inst ; См. функцию 4АН
exec pgm-file,cmd-line,parm-blk,0 ;
; Наша функция
ЗАГРУЗИТЬ НАЛОЖЕНИЕМ ( ФУНКЦИЯ 4ВН, КОД 03Н )
Вызов: АН = 4ВН
AL = 03H
DS:DX - указатель на маршрут
ES:BX - указатель на блок параметров
Возвращает: CF установлен:
АХ - 1 = несуществующая функция
2 = файл не найден
3 = маршрут не найден
4 = слишком много открытых файлов
5 = нет доступа
8 = мало памяти
10 = не та среда
CF сброшен:
нет ошибок
- 129 -
Комментарий:
Функция 4ВН (код 03Н) загружает программный сегмент
(накладку). DX должен содержать смещение (сегментный адрес в
DS) строки ASCIZ, указывающей маршрут программного файла. ВХ
должен содержать смещение (сегментный адрес в ES) блока
параметров. AL равно трем.
MS-DOS исходит из того, что родительская программа
загружает накладку в свое собственное адресное пространство, и
для этого не требуется дополнительной памяти. Эта функция не
создает Префикса сегмента кодов PSP.
Таблица 1.25
Содержимое блока параметров
__________________________________________________________
Смещение Длина Описание
(байты)
__________________________________________________________
00Н 2 Сегментный адрес, по которому загружается
прграмма
02Н 2 Фактор загрузки; обычно такой же, как и
первое слово блока параметров (описание
.exe файлов и загрузки см. в Главе 6,
"Cтруктура .EXE файлов и их загрузка")
__________________________________________________________
В случае ошибки устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
1 AL не 0 и не 3
2 Программный файл не найден
3 Несуществующий маршрут
4 Слишком много открытых файлов
5 Каталог заполнен, каталог с таким же именем уже
существует, или файл с таким же именем уже
существует
8 Не хватает памяти для загрузки программы
10 Длина среды превышает 32 килобайта
__________________________________________________________
Макроопределение:
exec-ovl macro path,parms,seg-addr
mov dx,offset path
mov bx,offset parms
mov parms,seg-addr
mov parms[02H],seg-addr
mov al,3
mov ah,4BH
int 21H
endm
Пример:
Следующая программа открывает файл textfile.asc,
назначает стандартный ввод этому файлу и загружает накладку
bit.com, которая читает этот файл как со стандартного ввода.
Накладка должна сама позаботится о своей системе адресации, и,
кроме того, должна заканчиваться FAR (дальним) возвратом.
- 130 -
stdin equ 0
;
file db "textfile.asc",0
cmd-file db "\bit.com",0
parm-blk dw 4 dup (?)
overlay label dword
dw 0
handle dw ?
new-mem dw ?
;
begin: set-block last-inst ; См. функцию 4АН
jc setblock-error ; Метка не показана
allocate-memory 2000 ; См. функцию 48Н
jc allocate-error ; Метка не показана
mov new-mem,ax ; Сохранить сегментный
; адрес памяти
open-handle file,0 ; См. функцию 3DH
jc open-error ; Метка не показана
mov handle,ax ; Сохранить хендл
xdup2 handle,stdin ; См. функцию 45Н
jc dup2-error ; Метка не показана
close-handle handle ; См. функцию 3ЕН
jc close-error ; Метка не показана
mov ax,new-mem ; Адрес новой памяти
exec-ovl cmd-file,parm-blk,ax ; Наша функция
jc exec-error ; Метка не показана
call overlay ; Вызов накладки
free-memory new-mem ; См. функцию 49Н
jc free-error ; Метка не показана
ЗАВЕРШИТЬ ПРОГРАММУ ( ФУНКЦИЯ 4СН )
Вызов: АН = 4СН
AL - код возврата
Возвращает: --
Комментарий:
Функция 4СН завершает программу и передает управление
MS-DOS. AL содержит код возврата, который может быть получен
родительской программой с помощью функции 4DH (Получить код
возврата дочерней программы) или с помощью команды IF,
используя ERRORLEVEL.
При вызове функции закрываются все открытые хендлы. Кроме
того, фунуция не требует загрузки в CS сегментного адреса
Префикса сегмента кодов. Вы можете пользоваться этой функцией
вместо прерывания 20Н, если, конечно, ваши программы не
нуждаются в совместимости с версиями системы до 2.0.
__________________________________________________________
Примечание
Если вы используете систему разделения файлов,
то вы должны снять блокировку, выставленную
этой системой, иначе DOS останется в неустой-
чивом положении.
__________________________________________________________
- 131 -
Макроопределение:
end-process macro return-code
mov al,return-code
mov ah,4CH
int 21H
endm
Пример:
Следующая программа выводит на экран сообщение и
возвращается в MS-DOS с кодом возврата 8. Использована только
открывающая часть скелета программы-примера, показанной в
начале этой главы.
message db "Это пример функции 4СН",0DH,0AH,"$"
;
begin: display message ; См. функцию 09Н
end-process 8 ; Наша функция
code ends
end code
ПОЛУЧИТЬ КОД ВОЗВРАТА ДОЧЕРНЕЙ ПРОГРАММЫ ( ФУНКЦИЯ 4DH )
Вызов: АН = 4DH
Возвращает: АХ - код возврата
Комментарий:
Функция 4DH возвращает код возврата, указываемый при
завершении дочерней программы с помощью функций 31Н (Сохранить
программу) или 4СН (Завершить программу). Код возврата
помещается в AL, a AH содержит код причины завершения:
Код Значение
__________________________________________________________
0 Обычное завершение
1 По CONTROL+C
3 Критическая ошибка устройства
4 С помощью функции 31Н (Сохранить программу)
__________________________________________________________
Функция возвращает код выхода только один раз.
Макроопределение:
ret-code macro
mov ah,4DH
int 21H
endm
Пример:
Пример не приводится, так как значения кода возврата
различны.
- 132 -
НАЙТИ ПЕРВЫЙ ФАЙЛ ( ФУНКЦИЯ 4ЕН )
Вызов: АН = 4ЕН
СХ - атрибуты
DS:DX - указатель на маршрут
Возвращает: CF (флаг переноса) установлен:
АХ - 2 = файл не найден
3 = маршрут не найден
18 = нет больше файлов
CF сброшен:
нет ошибок
Комментарий:
Функция 4ЕН ищет в текущем или указанном каталоге первый
вход, удовлетворяющий указанному маршруту. DX должен содержать
смещение (сегментный адрес в DS) строки ASCIZ , указывающей
маршрут, который, в свою очередь, может содержать символы
заполнители. СХ содержит используемый при поиске файла атрибут
(см. Раздел 1.5.5, "Атрибуты файла").
Если указаны атрибуты системный, скрытый или подкаталог
(04Н, 02Н или 10Н) или любая комбинация этих значений, то
обычные файловые входы также просматриваются. Для просмотра
всех каталоговых входов, за исключением входа с атрибутом ТОМ,
выставьте байт атрибута в 16Н (скрытый, системный и
каталоговый вход).
Если функция находит каталоговый вход, удовлетворяющий
имени и атрибуту, она заполняет текущий DTA (Буфер обмена с
диском) следующим образом:
Таблица 1.26
Значения DTA после успешного Поиска первого файла
__________________________________________________________
Смещение Длина Описание
__________________________________________________________
00Н 21 Зарезервировано для последующей функции
4FH (Найти следующий файл)
15Н 1 Найденный атрибут
16Н 2 Время последней записи в файл
18Н 2 Дата последней записи в файл
1АН 2 Младшее слово размера файла
1СН 2 Старшее слово размера файла
1ЕН 13 Имя и расширение файла, заканчивающееся
байтом 00Н. Все пробелы удалены. Если
расширение есть, то оно отделяется
точкой. (Файлы с атрибутом ТОМ включают
точку после 8 символа.)
__________________________________________________________
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
2 Указанный файл не разрешен или не существует
3 Указанный маршрут не разрешен или не существует
18 Не найден соответствующий каталоговый вход
__________________________________________________________
- 133 -
Макроопределение:
find-first-file macro path,attrib
mov dx,offset path
mov cx,attrib
mov ah,4EH
int 21H
endm
Пример:
Следующая программа сообщает, существует ли файл
report.asm в текущем каталоге на диске В.
yes db "Файл существует.",0DH,0AH,"$"
no db "Файл не существует.",0DH,0AH,"$"
path db "b:report.asm",0
buffer db 43 dup (?)
;
begin: set-dta buffer ; См. функцию 1АН
find-first-file path,0 ; Наша функция
jc error-findfirst ; Метка не показана
cmp al,12H ; Файл найден?
je not-there ; Нет
display yes ; См. функцию 09Н
jmp return ; Конец
not-there: display no ; См. функцию 09Н
НАЙТИ СЛЕДУЮЩИЙ ФАЙЛ ( ФУНКЦИЯ 4FH )
Вызов: АН = 4FH
Возвращает: CF установлен:
АХ = 18 - нет больше файлов
CF сброшен:
нет ошибок
Комментарий:
Функция 4FH ищет следующий каталоговый вход,
удовлетворяющий имени и атрибуту, указанным при вызове
предыдущей функции 4ЕН (Найти первый файл). Текущий DTA должен
содержать информацию, помещенную в него функцией 4ЕН.
Если функция находит соответствующий вход, она заполняет
DTA точно так же, как и функция 4ЕН.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
2 Указанный маршрут не разрешен или не существует
18 Не найден соответствующий каталоговый вход
__________________________________________________________
Макроопределение:
find-next-file macro
mov ah,4FH
- 134 -
int 21H
endm
Пример:
Следующая программа выводит на экран количество файлов,
содержащееся в текущем каталоге на диске В.
message db "Нет файлов",0DH,0AH,"$"
files dw ?
path db "b:*.*",0
buffer db 43 dup (?)
;
begin: set-dta buffer ; См. функцию 1АН
find-first-file path,0 ; См. функцию 4ЕН
jc error-findfirst ; Метка не показана
cmp al,12H ; Каталог пуст?
je all-done ; Да, возврат
inc files ; Нет, увеличить
; счетчик файлов
search-dir: find-next-file ; Наша функция
jc error-findnext ; Метка не показана
cmp al,12H ; Еще входы?
je all-done ; Нет, возврат
inc files ; Да, увеличить
; счетчик файлов
jmp search-dir ; и проверить еще раз
done: convert files,10,message ; См. конец главы
all-done: display message ; См. функцию 09Н
ПОЛУЧИТЬ СОСТОЯНИЕ ФЛАГА ПРОВЕРКИ ( ФУНКЦИЯ 54Н )
Вызов: АН = 54Н
Возвращает: AL - 0 = нет проверки после записи
1 = есть проверка после записи
Комментарий:
Функция 54Н выясняет, проверяет ли MS-DOS операции записи
на диск. Состояние возвращается в AL: 0, если проверка есть и
1, если проверки нет.
Вы можете запустить (включить) программу проверки с
помощью функции 2ЕН (Сброс/установка флага проверки).
Макроопределение:
get-verify macro
mov ah,54H
int 21H
endm
Пример:
Следующая программа показывает состояние флага проверки.
message db "Проверка - ","$"
on db "вкл.",0DH,0AH,"$"
off db "выкл.",0DH,0AH,"$"
- 135 -
;
begin: display message ; См. функцию 09Н
get-verify ; Наша функция
cmp al,0 ; Флаг сброшен?
jg ver-on ; Нет, он установлен
display off ; См. функцию 09Н
jmp return ; Конец
ver-on: display on ; См. функцию 09Н
ИЗМЕНИТЬ КАТАЛОГОВЫЙ ВХОД ( ФУНКЦИЯ 56Н )
Вызов: АН = 56Н
DS:DX - указатель на маршрут
ES:DI - указатель на второй маршрут
Возвращает: CF установлен:
АХ - 2 = файл не найден
3 = маршрут не найден
5 = нет доступа
17 = разные дисководы
CF сброшен:
нет ошибок
Комментарий:
Функция 56Н переименовывает файл путем изменения его
каталогового входа. DX должен содержать смещение (сегментный
адрес в DS) строки ASCIZ , содержащей маршрут изменяемого
входа. DI должен содержать смещение (сегментный адрес в ES)
строки ASCIZ, содержащей второй маршрут, на который будет
менятся первый.
Если каталоговый вход для первого маршрута существует, то
он изменяется на второй маршрут.
Так как каталоговые маршруты могут быть разными, вы
можете поместить файл в другой каталог переименовав его. В то
же время, вы не можете использовать эту функцию для
копирования файла на другой дисковод. Если второй маршрут
указывает дисковод, то первый маршрут должен указывать на тот
же дисковод явно или по умолчанию.
Вы не можете использовать эту функцию для переименования
открытых файлов, скрытых и системных файлов или подкаталогов,
так как это может испортить ваш диск.
В случае ошибки, устанавливается CF, а АХ возвращает код
ошибки:
Код Значение
__________________________________________________________
2 Один из файлов не существует
3 Один из маршрутов не существует
5 Первый маршрут указавает каталог, второй маршрут
указывает существующий файл; или второй
каталоговый вход не мог быть открыт
17 Файлы находятся на разных дисководах
__________________________________________________________
Макроопределение:
rename-file macro old-path,new-path
- 136 -
mov dx,offset old-path
push ds
pop es
mov di,offset new-path
mov ah,56H
int 21H
endm
Пример:
Следующая программа запрашивает имя файла, потом новое
имя, а затем переименовывает файл.
prompt1 db "Имя файла: $"
prompt2 db "Новое имя: $"
old-path db 15,?,15 dup (?)
new-path db 15,?,15 dup (?)
crlf db 0DH,0AH,"$"
;
begin: display prompt ; См. функцию 09Н
get-string 15,old-path ; См. функцию 0АН
xor bx,bx ; BL в качестве индекса
mov bl,old-path[1] ; Получить длину строки
mov old-path[bx+2],0 ; Сделать строку ASCIZ
display crlf ; См. функцию 09Н
display prompt2 ; См. функцию 09Н
get-string 15,new-path ; См. функцию 0АН
xor bx,bx ; BL в качестве индекса
mov bl,new-path[1] ; Получить длину строки
mov new-path[bx+2],0 ; Сделать строку ASCIZ
display crlf ; См. функцию 09Н
rename-file old-path[2],new-path[2] ; Наша
; функция
jc error-rename ; Метка не показана
ПОЛУЧИТЬ/УСТАНОВИТЬ ДАТУ/ВРЕМЯ ФАЙЛА ( ФУНКЦИЯ 57Н )
Вызов: АН = 57Н
AL - 0 = получить дату и время
1 = установить дату и время
ВХ - хендл
СХ (если AL=1) - время
DX (если AL=1) - дата
Возвращает: CF установлен:
АХ - 1 = несуществующая функция
6 = несуществующий хендл
CF сброшен:
СХ (если AL=0) - время последней
записи в файл
DX (если AL=0) - дата последней
записи в файл
Комментарий:
Функция 57Н получает или устанавливает время и дату,
когда в файл последний раз делалась запись. Содержимое
регистров показано выше. Формат представления времени и даты
показан в Разделе 1.9.1, "Поля Блока управления файлом (FCB)".
- 137 -
В случае ошибки, устанавливается флаг переноса (CF), а АХ
возвращает код ошибки:
Код Значение
__________________________________________________________
1 AL не 0 и не 1
6 Хендл в ВХ не существует или не открыт
__________________________________________________________
Макроопределение:
get-set-date-time macro handle,action,time,date
mov bx,handle
mov al,action
mov cx,word ptr time
mov dx,word ptr date
mov ah,57H
int 21H
endm
Пример:
Следующая программа получает дату файла report.asm,
находящегося в текущем каталоге на диске В, делает инкремент
дней, ( если необходимо, то и месяцев и/или лет) и
устанавливает для файла новую дату.
month db 31,28,31,30,31,30,31,31,30,31,30,31
path db "b:report.asm",0
handle dw ?
time db 2 dup (?)
date db 2 dup (?)
;
begin: open-handle path,0 ; См. функцию 3DH
mov handle,ax ; Сохранить хендл
get-set-date-time handle,0,time,date ; Наша
; функция
jc error-time ; Метка не показана
mov word ptr time,cx ; Сохранить время
mov word ptr date,dx ; Сохранить дату
convert-date date[-24] ; См. конец главы
inc dh ; Инкремент дней
xor bx,bx ; BL в качестве индекса
mov bl,dl ; Получить месяц
cmp dh,month[bx-1] ; Прошел последний
; день?
jle month-ok ; Нет, тогда конец
mov dh,1 ; Да, установить дни
; в 1
inc dl ; Инкремент месяца
cmp dl,12 ; Год прошел?
jle month-ok ; Нет, конец
mov dl,1 ; Да, установить
; месяцы в 1
inc cx ; Инкремент года
month-ok: pack-date date ; См. конец главы
get-set-date-time handle,1,time,date ; Наша
; функция
jc error-time ; Метка не показана
close-handle handle ; См. функцию 3ЕН
jc error-close ; Метка не показана
- 138 -
УСТАНОВИТЬ/ПОЛУЧИТЬ СТРАТЕГИЮ ВЫДЕЛЕНИЯ ПАМЯТИ
( ФУНКЦИЯ 58Н )
Вызов: АН = 58Н
AL - 0 = получить стратегию
1 = установить стратегию
ВХ (если AL=1) - 0 = первый подходящий
1 = по размеру
2 = последний
подходящий
Возвращает: CF установлен:
АХ = 1 - несуществующий код
функции
CF сброшен:
АХ (если AL=0) -
0 = первый подходящий
1 = по размеру
2 = последний
подходящий
Комментарий:
Функция 58Н получает или устанавливает стратегию, которую
MS-DOS использует для выделения памяти программам, когда
последние делают запрос на выделение памяти. Если AL = 0, то
стратегия возвращается в АХ. Если AL = 1, то ВХ должен
содержать стратегию.
Таблица 1.27
Стратегия выделения памяти
__________________________________________________________
Номер Имя Описание
__________________________________________________________
0 Первый MS-DOS начинает поиск доступных
подходящий блоков с меньших адресов
и выделяет первый подходящий.
Эта стратегия устанавливается по
умолчанию.
1 По размеру MS-DOS просматривает все доступ-
ные блоки и выделяет наименьший
подходящий.
2 Последний MS-DOS начинает поиск доступных
подходящий блоков со старших адресов
и выделяет первый подходящий.
__________________________________________________________
Вы можете использовать эту функцию для контроля за
выделением памяти.
В случае ошибки устанавливается CF (флаг переноса), а АХ
возвращает код ошибки:
Код Значение
__________________________________________________________
1 AL не 1 и не 0, или ВХ не 0, не 1 и не 2
Макроопределение:
alloc-strat macro code,strategy
mov bx,strategy
- 139 -
mov al,code
mov ah,58H
int 21H
endm
Пример:
Следующая программа выводит на экран действующую
стратегию выделения памяти, после чего устанавливает стратегию
с кодом 2 ( выделение памяти, начиная со старших адресов).
get equ 0
set equ 1
stdout equ 1
last-fit equ 2
;
first db "First fit ",0DH,0AH
best db "Best fit ",0DH,0AH
last db "Last fit ",0DH,0AH
;
begin: alloc-strat get ; Наша функция
jc alloc-error ; Метка не показана
mov cl,4 ; Умножить код на 16
shl ax,cl ; для вычисления
; смещения, и прибавить
mov dx,offset first ; к базе (dx) первого
add dx,ax ; сообщения (first)
mov bx,stdout ; В ВХ хендл для записи
mov cx,16 ; шестнадцати байт
mov ah,40H ; Функция - Записать в
int 21H ; хендл
jc write-error ; Метка не показана
alloc-strat set,last-fit ; Наша функция
jc alloc-error ; Метка не показана
ПОЛУЧИТЬ РАСШИРЕННЫЙ КОД ОШИБКИ ( ФУНКЦИЯ 59Н )
Вызов: АН = 59Н
ВХ = 00Н
Возвращает: АХ - расширенный код ошибки
ВН - класс ошибки (см. текст)
BL - предполагаемые действия (см. текст)
СН - локализация (см. текст)
Регистры CL,DX,SI,DI,DS,ES не сохраняются
Комментарий:
Функция 59Н возвращает расширенный код ошибки для
системного вызова, предшествующего вызову этой функции. Каждая
новая версия MS-DOS вводит новые коды ошибок, выход к которым
может осуществляется параллельно с тем небольшим набором
кодов, основанным на версии системы 2.0. Таким образом, уже
написанные программы будут совместимы с новыми версиями.
Обратите внимание на то, что эта функция разрушает все
регистры, кроме CS:IP и SS:SP.
Написанная пользователем программа обработки прерывания
24Н (Прерывание по критической ошибке) может получить
- 140 -
детальную информацию об ошибке, вызвавшей прерывание.
Содержимое ВХ - это индикатор версии, указывающий
уровень анализа ошибок написанной процедуры. Текущий уровень 0.
Расширенный код состоит из четырех отдельных
кодов в AX,BH,BL и СН, дающих подробную информацию об ошибке и
предполагаемой реакции программы, обратившейся к этой функции.
ВН - Класс ошибки:
Класс Описание
__________________________________________________________
1 Нет ресурсов, например, памяти или каналов
2 Не ошибка, а временное состояние (например, бло-
кирована область файла)
3 Не имеет права
4 Внутренняя ошибка в системной программе
5 Технический сбой
6 Ошибка системы, а не действующей программы (может
быть вызвана отсутствием или некорректностью
файлов конфигурации, например)
7 Ошибка прикладной программы
8 Файл или объект не найден
9 Файл или объект неправильного типа или формата,
или, другими словами, не разрешены, не существуют
или не подходят
10 Файл или объект блокированы в сети
11 Плохой диск или другие проблемы с накопителем
12 Другие ошибки
__________________________________________________________
BL - предполагаемые действия:
Действие Описание
__________________________________________________________
1 Повторить, затем сделать запрос пользователю
2 Повторить после паузы
3 Если пользователь вводил имя диска или файла,
то запросить их еще раз
4 Закончить с завершающими процедурами
5 Закончить немедленно; система настолько разла-
жена, что программа должна выйти как можно скорее,
не тратя времени на закрытие файлов и обновление
индексов
6 Информационная ошибка
7 Запросить пользователя выполнить некоторые
действия (сменить диск, например) и повторить
операцию
__________________________________________________________
СН - локализация:
Код Описание
__________________________________________________________
1 Неизвестная
2 Связана с блоковым устройством выборочного
доступа ( дисковод, например)
3 Связана с Сетью
4 Связана с символьным устройством последователь-
ного доступа ( принтер, например)
5 Связана с оперативной памятью
__________________________________________________________
- 141 -
Если при обращении вашей программы к какой-либо функции
возвращен код ошибки, то ваша программа сразу после получения
такого кода может обратиться к функции 59Н для получения уже
расширенного кода. Если в этом нет необходимости, то программа
обходится кодом, возвращаемым первой функцией.
Функция 59Н доступна во время прерывания 24Н и может быть
использована для возврата сетевых ошибок.
Макроопределение:
get-error macro
mov ah,59H
int 21H
endm
Пример:
Так как эта функция дает детальную информацию об ошибке,
общий пример не приводится. Программы пользователя могут
интерпретировать возвращаемые коды для определения видов
сообщений и запросов, посылаемых на экран, действий, которые
необходимо предпринять, или для прекращения программы, если
исправить последствия ошибки невозможно.
©
KOAP Open Portal 2000
|
|