Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бочков C.. Язык программирования Си для персонального компьютера - royallib.ru.doc
Скачиваний:
39
Добавлен:
11.03.2016
Размер:
901.98 Кб
Скачать

Модификация стандартной модели памяти

Работая в некоторой стандартной модели памяти, программист может в той или иной мере модифицировать ее, применяя в объявлениях модификаторы near , far и huge . Правила интерпретации объявлений с модификаторами рассмотрены в разделе 3.3.3.4 "Модификаторы near , far , huge ".

Объявление данных

Если непосредственно за ключевым словом near , far или huge следует идентификатор, то это значит, что соответствующий элемент данных будет размещен в стандартном сегменте (для near ) или может быть размещен в другом сегменте данных (для far или huge ). Например, объявление

char far х;

сообщает, что адрес объекта х имеет тип far.

Если же непосредственно за ключевым словом near , far или huge следует признак указателя (звездочка), то это значит, что соответствующий указатель будет хранить адрес типа near , типа far или типа huge , соответственно. Например, объявление

char far *р;

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

char * far р;

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

char far * far р;

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

Примеры:

char а[3000]; /* пример 1: малая модель */

char far b[30000]; /* пример 2: малая модель */

char a[3000]; /* пример 3: большая модель */

char near b[3000]; /* пример 4: большая модель */

char huge a[70000]; /* пример 5: малая модель */

char huge *pa; /* пример 6: малая модель */

char *pa; /* пример 7: малая модель */

char far *pb; /* пример 8: малая модель */

char far **pa; /* пример 9: малая модель */

char far **pa; /* пример 10: большая модель */

char far *near *pb; /* пример 11: любая модель */

char far *far *pb; /* пример 12: любая модель */

В примере 1 массиву а выделяется память в стандартном сегменте данных; массиву b во втором примере память может быть выделена в любом из сегментов данных программы. Поскольку оба объявления сделаны в малой модели, то, вероятно, массив а содержит часто используемые данные, которые для ускорения доступа должны располагаться в стандартном сегменте, а массив b содержит редко используемые данные, которые могут выйти за пределы 64-Кбайтного сегмента данных. Можно было бы использовать здесь другую модель памяти, в которой адрес данных по умолчанию имел бы тип far , однако для сохранения быстрого доступа к массиву а лучше сохранить малую модель, а адрес массива b объявить как far .

В примере 2 указан большой размер массива b , поскольку более вероятно, что программист будет модифицировать тип адреса объекта большой длины, который может не поместиться в текущий сегмент.

В примере 3, очевидно, скорость доступа к массиву а не является критичной; независимо от того, попадет он в стандартный сегмент или не попадет, обращение к нему всегда будет осуществляться по 32-битовому адресу. В примере 4 массиву b с помощью модификатора near явно назначен стандартный сегмент, с целью ускорения доступа к нему в большой модели.

В примере 5 массив а должен быть явно объявлен как huge , поскольку его размер превышает 64 Кбайта. Использование модификатора huge вместо выбора максимальной модели памяти в качестве стандартной позволяет сэкономить время доступа: только к массиву а обращение будет осуществляться по адресу типа huge , а все остальные данные будут размещаться в стандартном сегменте. Для обращения к массиву а может быть использован указатель ра из примера 6. Все арифметические операции над указателем ра (например, ра++ ) будут выполняться над всеми 32 его битами.

В примере 7 ра объявляется как указатель на near char . Указатель получает тип near по умолчанию, поскольку речь идет о малой модели. В примере 8 pb явно объявляется как указатель на far char . Он может быть использован, в частности, для доступа к символьному массиву, расположенному не в стандартном сегменте памяти. Например, ра может указывать на массив а из примера 1, а pb — на массив b из примера 2.

Хотя объявления ра в примерах 9 и 10 идентичны, в примере 9 ра объявляется как указатель на near массив указателей на тип far char , а в примере 10 ра объявляется как указатель на far массив указателей на тип far char .

В примере 11 pb объявляется как указатель на near массив указателей на тип far char . В примере 12 pb объявляется как указатель на far массив указателей на тип far char . В этих примерах употребление слов far и near изменяет действующие по умолчанию соглашения, связанные с моделями памяти; в отличие от примеров 9 и 10, объявления pb не зависят от выбранной модели памяти и в любой модели имеют одинаковый смысл.