5.2.1. Совмещение адресов директивой absolute

Турбо Паскаль позволяет управлять при необходимости размещением значений переменных в памяти (ОЗУ). Для этой цели

- 80 -

служит директива absolute с последующим указанием адреса. Возможны два формата задания адреса, с которым в принудительном порядке будет связана переменная. Первый формат — это указание физического адреса нужной ячейки памяти:

| TYPE

| ByteArray1_10 = Array [1..10] of Byte;

| VAR

| Memory : Byte absolute $0000:$0417;

| SystemV : ByteArray1_10 absolute $B800:$0000;

| MemWord : Word absolute $0:$2;

He вдаваясь в подробности задания самого адреса $...:$..., важно отметить, как будут размещены в дальнейшем значения переменных. Все они, вместо того чтобы в порядке следования разместиться в сегменте данных, будут хранить свои значения в явно заданных (абсолютных) адресах. Причем адрес, указываемый после слова absolute, задает первый байт значения. Так, переменная Memory будет хранить и выдавать текущее значение байта системной памяти. Она же будет изменять его присваиваниями типа

Memory := 16;

{ Теперь байт по адресу $0:$417 содержит значение 16. }

Массив SystemV будет начинаться в памяти с указанного ему абсолютного адреса. В данном случае абсолютный адрес будет адресом первого элемента массива, и в этой ячейке будет хранится значение System[1]. Следующий элемент будет расположен сразу за первым в порядке возрастания адреса. Последний, десятый, элемент массива System будет соответствовать значению, хранящемуся в десятой, начиная с абсолютного адреса, ячейке памяти. И, наконец, значение длиной в слово (Word — 2 байта) MemWord будет соответствовать двум последовательным байтам памяти, первый из которых задан его абсолютным адресом в директиве absolute.

Другой формат использования слова absolute служит для совмещения описываемой переменной не с абсолютным адресом ячейки, а с адресом уже объявленной ранее переменной:

| TYPE

| RArray4Type = Array [1..4] of Real;

| Rec4Type = RECORD x1,y1,x2,y2 : Real

| END;

| VAR

| X : Word;

| Y : Word absolute X;

- 81 -

{ массив из четырех значений типа Real: }

dim : RArray4Type;

{ запись из четырех значений типа Real: }

rec : Rec4Type absolute dim;

В этом примере имена X и Y — разные идентификаторы одного и того же значения. Изменение значения X равносильно изменению значения Y, ибо после объявления Y с указанием 'absolute X', ее значение будет располагаться в тех же ячейках памяти, что и X. Но для X до этого будет отведено место обычным путем — в сегменте данных. Можно совмещать разнотипные переменные, как это сделано с dim и rec. Запись с четырьмя полями вещественного типа совмещена со значением массива из четырех таких же чисел. После объявления 'absolute dim' становятся эквивалентными обращения

dim[1] и rec.x1,

dim[2] и rec.y1,

dim[3] и rec.x2,

dim[4] и rec.y2 .

Разрешение подобных совмещений открывает большие возможности для передачи значений между различными частями программ и их использования. Директива absolute — это подобие средств организации COMMON-блоков и оператора EQUIVALENCE в языке Фортран.

При совмещении переменных сложных типов (например, dim и rec) их типы не должны конструироваться по ходу объявления, а обязаны быть введены ранее в блоке TYPE. Нарушение этого правила компилятором практически не анализируется, а последствия его могут быть самыми неприятными, вплоть до «зависания» ПЭВМ (особенно при работе с сопроцессором).

Формально размеры совмещаемых переменных не обязаны быть одинаковыми. Совмещение по имени переменной — это, по сути, совмещение их начал. Поэтому можно использовать такие приемы:

| VAR

| St : String[30];

| StLen : Byte absolute St;

Здесь значение StLen совмещено со значением текущей длины строки St, которое хранится в элементе строки St[0]. Не рекомендуется совмещать большие по длине переменные с меньшими. Если в последнем примере запись значения в StLen может попортить лишь строку St, то в случае

- 82 -

| VAR

| StLen : Byte;

| St : String absolute StLen;

Другие объявления;

изменение St изменит не только байт StLen, но и значения тех переменных, которые будут объявлены после St.

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

Совмещение переменных — мощное, но очень опасное при неумелом обращении средство. Помните об этом!