; раграфах).
;
; Вход : ES = адрес сегмента распределенного блока памяти
; BX = новый размер в 16-байтных параграфах
;
; Выход : Признак переноса = 0, если УСПЕХ, причем
; (Содержимое всех регистров восстанавливается)
; Признак переноса = 1, если ОТКАЗ, причем
; AX = код ошибки,
; 7 = разрушенные блоки управления памятью
; 8 = недостаточная память
; 9 = недействительный адрес блока
; BX = наибольший доступный блок памяти в
; параграфах, если AX = 8,
; в противном случае, содержимое его
; восстанавливается.
; (Содержимое регистра ES восстанавливается)
;
; Вызываемые стандартные программы: нет
;- - - - - - - - - - - - - - - - - - - - - - - - - - -
PUBLIC MEMSIZE ; библиотечная стандартная программа
;
memsize PROC NEAR
push bp ; сохранить указатель базы
push es ; сохранить адрес блока памяти
push ax ; сохранить регистр AX
push bx ; сохранить регистр BX
mov bp,sp ; инициализировать указатель базы
;
xor al,al ; очистить регистр AL
mov ah,4Ah ; загрузить функцию и изменить
; размер блока
@DosCall
jnc end_memsize ; завершить выполнение,
; если нет ошибки
; в противном случае, завершить выполнение
; с установкой признака переноса
pushf ; сохранить признаки
cmp ax,8 ; памяти недостаточно?
jne memsize_err ; нет, продолжить
mov word ptr [bp],bx ; в противном случае,
; сохранить максимально доступный размер
memsize_err:
mov word ptr [bp+2],ax ; сохранить код ошибки
popf ; восстановить признаки
;
end_memsize:
pop bx ; восстановить содержимое регистров
pop ax
- П-40 -
pop es
pop bp ; восстановить указатель базы
ret
;
memsize ENDP
;
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++
; MEMFREE - Освобождает блок памяти, ранее распределенный
; стандартной программой MALLOC.
;
; Вход : ES = адрес сегмента распределенного блока памяти
;
; Выход : Признак переноса = 0, если УСПЕХ
; (Содержимое регистра ES восстанавливается)
; Признак переноса = 1, если ОТКАЗ, причем
; AX = код ошибки,
; 7 = разрушенные блоки управления памятью
; 9 = недействительный адрес блока
; (Содержимое регистра ES восстанавливается)
;
; Вызываемые стандартные программы: нет
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
PUBLIC MEMFREE ; библиотечная стандартная программа
;
memfree PROC NEAR
push bp ; сохранить указатель базы
push es ; сохранить адрес блока памяти
push ax ; сохранить регистр AX
mov bp,sp ; инициализировать указатель
; базы
xor al,al ; очистить регистр AL
mov ah,49h ; загрузить функцию осво-
; бождения памяти
@DosCall ; выполнить освобождение памяти
jnc end_memfree ; завершить выполнение,
; если нет ошибки
; в противном случае, завершить выпол-
; нение с установкой признака переноса
mov word ptr [bp],ax ; и кодом ошибки (регистр AX)
;
end_memfree:
pop ax ; восстановить содержимое регистра AX
pop es ; восстановить адрес блока
pop bp ; восстановить указатель базы
ret
;
memfree ENDP
;
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; MERRHNDL - Обработка ошибки распределения памяти/ос-
; вобождения памяти (повторного задания размера).
;
; Вход : AX = код ошибки
; BX = наибольший доступный блок памяти
- П-41 -
; (если код ошибки = 8)
; ES = адрес сегмента распределенного блока памяти
; (если код ошибки = 9)
;
; ES = адрес сегмента распределенного блока памяти
;
; Выход : нет (содержимое всех регистров восстанавливается)
;
; Вызываемые стандартные программы:
; BIN2CON (отображает номера в десятичном виде)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
PUBLIC MERRHNDL ; библиотечная стандартная программа
;
merrhndl PROC NEAR
;
cmp ax,7 ; очищены блоки управления памятью?
jne mem_error8 ; нет, продолжить проверку
@DisStr TrashedMemErr_Msg; да, завершить выполнение
; сообщением
ret ; вернуться
;
mem_error8:
cmp ax,8 ; памяти недостаточно?
jne mem_error9 ; нет, продолжить проверку
@DisStr InsuffMemErr_Msg ; да, завершить выполнение
; сообщением
@DisNum bx,10,1,0 ; и наибольшим доступным блоком
; памяти
@Newline ; отобразить пустую строку
ret ; вернуться
;
mem_error9:
cmp ax,9 ; адрес блока памяти
; недействителен?
jne mem_err_unknown ; нет, неизвестна причина
@DisStr IncorrSegAddr_Msg; отобразить сообщение об
; ошибке
@DisNum es,16,4 ; отобразить адрес сегмента
@NewLine ; отобразить пустую строку
ret ; вернуться
;
mem_err_unknown:
@DisStr UnknownMemErr_Msg ; вывести сообщение
ret
;
_TEXT ENDS ; конец сегмента текста программы
_DATA SEGMENT ; начало сегмента данных
trashedMemErr_Msg db ""Сбой при распределении памяти: управ-"
db "ляющие блоки памяти разрушены.",CR,LF,"$"
InsuffMemerr_Msg db ""Сбой при памяти: "
db "Недостаточно памяти",CR,LF
db "наибольший доступный блока памяти = $"
IncorrSegAddr_Msg db "Неправильный адрес сегмента для "
db "повторного задания размера/освобождения.",CR,LF
db "Адрес сегмента = $"
UnknownMemErr_Msg db "Неизвестная ошибка при распределении/"
db "повторном задании размера/освобождении "
- П-42 -
db "памяти.",CR,LF,"$"
_DATA ENDS ; конец сегмента данных
_TEXT SEGMENT ; начало сегмента программы
;
merrhndl ENDP
;
;
;********************************************************
; Конец стандартных библиотечных программ
;********************************************************
_ТEXT ENDS
END
----------------------------------------------------------------
Как видно из листинга, все стандартные программы должны быть
описаны в исходном файле как PUBLIC (общего пользования) с тем,
чтобы сделать их доступными для других программ. Любая метка (ко-
торая представляет собой то же, что и имя стандартной программы),
подлежащая использованию в других программах, должна быть описана
таким образом.
Если стандартные программы должны включаться в .EXE-файлы,
то единственное что необходимо - это использовать управляющую ко-
манду EXTRN, помещенную "за пределами описания сегмента". Редак-
тор связей LINK находит данную ссылку в библиотеке и помещает
стандартную программу, на которую идет ссылка в ее собственный
сегмент в окончательной программе. Однако, если эти стандартные
программы должны включаться в файлы типа .COM, то оба имени и
сегмента и "класса", используемые для .COM - программы, должны
соответствовать именам, используемым в стандартной библиотечной
программе.
Чтобы использовать стандартные программы BIN2DEC или BIN2НEХ
программа типа .COM должна использовать следующее описание сег-
мента:
code segment para public "code"
Отметим, что описание данного сегмента должно быть определе-
но как PUBLIC. В этом случае и имя сегмента (code) и имя класса
('code') одинаковы, чтобы облегчить их запоминание. Кроме того уп-
равляющие команды EXTRN должны быть помещены в описание сегмента,
что позволит макроассемблеру MASM знать, какие внешние стандартные
программы являются составной частью этого сегмента. (Метки PUBLIC
и EXTRN даются атрибутам того же сегмента, что и сегмента, который
включает их описания).
Дополнительная информация относительно библиотечных стан-
дартных программ, меток PUBLIC и EXTRN можно найти в справочных
руководствах по макроассемблеру MASM и редактору связей LINK фир-
мы "Майкрософт".
- П-43 -
Приложение Б. НЕ ОПИСАННЫЕ В ДОКУМЕНТАЦИИ ПО
ОПЕРАЦИОННОЙ СИСТЕМЕ MS-DOS ПРЕРЫВАНИЯ И ФУНКЦИИ
Не описанные в документации прерывания операционной
системы MS-DOS
Не описанные в документации вызовы функций прерывания 21h(33)
В этом приложении приводится описание некоторых не описанных
в документации средств операционной системы MS-DOS. В частности,
описываются прерывания MS-DOS и функции, связанные с этими преры-
ваниями. "Не описанные в документации" относятся к таким средс-