Программирование для защищенного режима 225

LoWord(LongInt(P)) + LoWord(Offset))

не приведет к переполнению значения Word. Это будет только тогда, когда смещение указателя Р нулевое. Если это не так, то в общем случае потребуется дополнительная проверка

if LongInt(LoWord(LongInt(P)))+LoWord(Offset)>$FFFF then {Наращиваем селекторную часть на Selectorinc}

К счастью, смещение в адресах, возвращаемых функциями GlobaILock и GlobalAllocPtr, всегда нулевое и функция не осуществляет ненужную проверку.

В следующей несложной программе иллюстрируется техника работы с большими блоками. Программа резервирует блок размером почти 1 Мбайт для распределения в нем 250000 значений типа Longint, заполняет этот массив монотонно возрастающими значениям от 1 до 250000 и затем находит сумму всех его элементов. Найденная сумма выводится вместе с теоретическим значением, что позволяет убедиться в достоверности результата.

{$N+,E+} {Используем сопроцессор для типа Сотр} Uses WinAPI;

Function GetPtr(P: Pointer; Offset: Longint'): Pointer;

begin

GetPtr := Ptr(

HiWord(LengIntCP)) + HiWord(Offset)*SelectorInc, LoWord(Longint(P)) + LoWord(Offset)) end;

type

PLongInt =ALongInt;

const

MaxSize = 250000;

var

Summ : Comp;

k : Longint;

Buffer: Pointer;

begin

Buffer := GlobalAllocPtr(gmem_Moveable,MaxSize*4^;

for k := 1 to MaxSize do

PLongInt (GetPtr (Buf fer, (k-DM))'" := k;

Summ := 0;

for k := 1 to MaxSize do

Summ := Summ + PLongInt(GetPtr(Buffer,(k-1)*4))л;

GlobalFreePtr(Buffer) ;

WriteLn(Summ:10:0, (1.O*MaxSize*MaxSize+MaxSize)/2:15:0) end.

(умножение на 1.0 в выражении

(l.O*MaxSize*MaxSize+MaxSize)/2