Переменная SelectorInc модуля System содержит значение, ко- торое должно прибавляться к селектору или вычитаться из него для получения следующего или предыдущего селектора в таблице дескрип- торов. SelectorInc полезно использовать при работе с большими блоками памяти (превышающими 64К) и при доступе к псевдонимам сегментов.
Для выделения блоков, превышающих 64К (такие блоки называют также большими блоками памяти), можно использовать функции GlobalAlloc и GlobalAllocPrt в модуле WinAPI. Большие блоки неп- рерывны в физической памяти, но из-за 16-разрядной архитектуры процессора прикладная программа не может получить к ним доступ целиком. Для большого блока памяти администратор памяти выделяет несколько непрерывных (следующих подряд) селекторов, каждый из которых (кроме последнего) ссылается на часть большого блока па- мяти размером 64К. Например, чтобы выделить блока памяти размером в 220К, администратор памяти создает четыре селектора, при этом первые три селектора ссылаются на блоки по 64К, а последний се- лектор - на блок размером 28К. Прибавляя SelectorInc к селектору, принадлежащему большому блоку, вы можете получить селектор для следующего сегмента, а вычитая SelectorInc - для предыдущего.
При распределении большого блока функция GlobalAlloc всегда возвращает описатель первого сегмента, а GlobalAllocPtr - указа- тель на первый сегмент.
Приведенная ниже функция GetPtr воспринимает указатель боль- шого блока (возвращаемый функцией GlobalAllocPtr) и 32-разрядное смещение и возвращает указатель на заданное внутри блока смеще- ние.
function GetPtr(P: Pointer; Offset: Longint): Pointer; type Long = record Lo, Hi: Word; end;
begin GetPtr := Ptr(
Long(P).Hi + Long(Offset).Hi * SelectorInc, Long(P).Lo + Long(Offset).Lo); end;
Заметим, что старшее слово параметра Offset используется для определения того, сколько раз нужно увеличить селекторную часть P для получения корректного сегмента. Например, если Offset равно $24000, то селекторная часть P будет увеличена на 2 * SelectorInc, а смещение P - на $4000.