Программирование для защищенного режима 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