TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

Переменная SelectorInc 

             Переменная 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.

             Следующая функция LoadFile загружает в блок памяти весь файл
        и возвращает указатель на блок. Если файл превышает 64К, то выде-
        ляется большой блок памяти.

             function LoadFile(const FileName: string): Pointer;
             var
               Buffer: Pointer;
               Size, Offset, Count: Longint;
               F: file;
             begin
               Buffer := nil;
               Assign(F, FileName);
               Reset(F, 1);
               Size := FileSize(F);
               Buffer := GlobalAllocPtr(gmem_Moveable, Size);
               if Buffer <> nil then
               begin
                 Offset := 0;
                 while Offset < Size do
                 begin
                    Count := Size - Offset;
                    if Count > $8000 then Count := $8000;
                    BlockRead(F, GetPtr(Buffer, Offset)^, Count);
                    Inc(Offset, Count);
                 end;
               end;
               LoadFile := Buffer;
             end;

             Переменная SelectorInc  определена  также  в  версии  модуля
        System для реального режима.  В реальном режиме она всегда содер-
        жит значение $1000,  которое при сложении его с сегментной частью
        указателя реального режима увеличивает указатель на 64К.

             Другим образом вы можете использовать переменную SelectorInс
        только в программах DOS защищенного режима.  Используйте перемен-
        ную SelectorInc для доступа к псевдонимам  сегментов,  выделяемых
        администратором этапа выполнения при загрузке прикладной програм-
        мы.  Для каждого сегмента кода прикладной программы администратор
        этапа  выполнения создает селектор-псевдоним,  ссылающийся на тот
        же сегмент, но имеющий полномочия селектора данных. Для сегментов
        стека и данных селекторы-псевдонимы не создаются.
             Чтобы получить доступ к селектору-псевдониму для конкретного
        сегмента, добавьте к селектору сегмента SelectorInc. Предположим,
        например,  что P - это переменная типа Pointer, а Foo - процедура
        или функция. Тогда присваивание вида:

             P := Addr(Foo)

        приводит к  тому,  что P будет указывать на выполняемую доступную
        только по чтению точку входа Foo, а после оператора:

             P := Ptr(Seg(Foo) + SelectorInc, Ofs(Foo));

        P будет ссылаться на тот же адрес,  но  с  полномочиями  на  чте-
        ние/запись.




Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz