Таким образом, для нормальной загрузки программы необходимо, чтобы в текущем каталоге или в одном из каталогов, перечисленных в переменной окружения PATH, находились все используемые программой DLL— библиотеки, а также файлы DPMI16BLOVL и RTM.EXE.

Программирование в защищенном режиме почти не отличается от программирования для MS-DOS. Единственное, о чем не должен забывать программист, это о специфике использования памяти.

В защищенном режиме нельзя использовать абсолютные адреса, задаваемые директивой absolute. Точнее, их можно указывать только в сочетании с одним из следующих стандартных селекторов:

Seg0040 определяет начало области параметров BIOS;

SegAOOO начало видеопамяти адаптеров EGA/VGA в графическом режиме;

SegBSOO начало видеопамяти адаптеров CGA/EGA/VGA в текстовом режиме;

SegBOOO начало видеопамяти монохромных адаптеров.

Только с правильными селекторами можно использовать массивы памяти Mem, MemW и MemL. Селектором должен быть и первый параметр обращения к функции Ptr, которая используется для создания указателей.

В защищенном режиме размер кучи определяется объемом всей оператчвной памяти компьютера за вычетом загруженной программы и резидентных частей MS-DOS, расширителя ДОС и DPMI— сервера. Хотя функции ClobaIAIIoc и GlobalAllocPtr способны распределять в куче блоки очень большие блоки (до 64 Мбайт), использовать данные в крупных блоках можно только порциями по 64 Кбайт, т.к. смещение в указателях задается 16—разрядным словом. Учитывая это, расширитель ДОС при распределении в куче крупного блока создает несколько последовательно расположенных селекторов, каждый из которых (кроме, возможно, последнего) ссылается на участок памяти длиной 64 Кбайт. Возвращаемый функциями GlobaILock и GlobalAllocPtr указатель содержит селектор и смещение, определяющие адрес самого первого байта крупного блока. Для доступа к остальным байтам в этом случае можно использовать следующую функцию:

Function GetPtr(P: Pointer; Offset: LongInt): Pointer/begin

GetPtr := Ptr(

HiWord(LongInt(P)) + HiWord(Off set)*SelectorInc,

LoWord(LongInt(P)) + LoWord(Offset)) end;

При рализации этой функции используются два обстоятельства. Во-первых, старшее слово 32 — разрядного параметра Offset содержит количество блоков по 65535 байт и поэтому для получения селекторной части указателя это слово умножается на Selectorinc (вариант

round(Offset/65535)*SelectorInc

дает такой же результат, но реализуется значительно медленно). Во-вторых, предполагается, что сложение