10.5.2. Создание адреса функцией Ptr

Функция Ptr( Seg, Ofs : Word) выполняет противоположную функции Addr работу: организует ссылку на место в памяти, определяемое заданными сегментом и смещением. Необходимость в такой функции возникает всякий раз, когда требуется наложить динамическую структуру на системную область памяти (системные, т.е. зарезервированные, области памяти достаточно жестко фиксированы, и их адреса описаны в специальной литературе). Если, например, известно, что образ текстового экрана начинается с адреса $В000 : $0000 и занимает 4000 байт (цветной и черно-белый режимы, 80 столбцов на 25 строк), то можно «наложить» на него структуру, например массив, используя ссылку на такой массив и функцию Ptr (рис. 10.2):

| TYPE

| VideoArray = Array [0..3999] of Byte;

| VAR

| V : ^VideoArray; { ссылка на структуру }

| BEGIN

| V := Ptr( $B000, 0 );

| { Далее V^[i] обращается непосредственно к ячейкам видеопамяти в текстовом режиме }

| ...

| END.

Рис. 10.2

Обращаем внимание на отсутствие вызовов New и Dispose. Они не нужны, так как массив буквально накладывается, а не создается вновь.

Так как значение типа Pointer, возвращаемое функцией Ptr, совместимо со всеми ссылочными типами, можно наложить любую структуру на какой угодно участок памяти. Кроме того, его разрешается разыменовывать, т.е. записывать конструкции вида

Ptr( $40, $40 )^

- 193 -

Но в чистом виде такая конструкция имеет мало смысла, ибо не определена структура, на первый байт которой указывает это разыменование. А определить эту структуру можно операцией приведения (преобразования) типа:

B := Byte( Ptr($40, $40)^); {B — значения байта $40:$40 }

W := Word( Ptr($40,$40)^ ); { W — значение слова $40:$40 }

X := VideoArray( Ptr($B800,0)^); { X — статический массив типа VideoArray содержит теперь в себе образ видеопамяти (текстовое изображение) }

и т.д.

Не стоит только приводить к типу String и производным от него: никогда не известно, что окажется в нулевом элементе строки, где должен храниться ее реальный размер.