В большой (large) модели и под код, и под данные выделяется несколько сегментов. Большая модель используется для больших программ с большим объемом данных.
В большой модели доступ к элементам кода и данных производится по указателям типа far. Это умолчание можно обойти, используя модификаторы near и huge для объявления данных и модификатор near для функций.
Максимальная модельМаксимальная (huge) модель аналогична большой модели, за исключением того, что в ней снимается ограничение на размер массивов (указатели типа far, применяемые в большой модели, ограничивают размер отдельного элемента данных 64 Кбайтами). Некоторые ограничения, однако, налагаются на размер элементов huge массивов, если эти массивы превышают по размеру 64 Кбайта. В целях повышения эффективности адресации не допускается пересечения элементами массива границ сегмента. Из этого вытекает следующее:
1) Никакой элемент массива не может превышать по размеру 64 Кбайта.
2) Если размер массива больше 128 Кбайтов, размер его элементов (в байтах) должен быть степенью двойки (т. е. 2, 4, 8, 16 и т.д.). Если же размер массива меньше или равен 128 Кбайтам, то размер его элементов может быть от 1 байта до 64 Кбайтов (включительно).
Работая в максимальной модели, программист должен быть осторожен в применении операции sizeof и при вычитании указателей. В языке Си определено, что значение операции sizeof имеет тип unsigned int, однако число байтов в huge массиве может быть представлено только типом unsigned long. Для получения правильного значения в этом случае следует применять приведение типа операции sizeof:
(unsigned long)sizeof(huge_item)
Аналогично, результат вычитания указателей определен в языке Си как значение типа int. При вычитании указателей типа huge может оказаться, что результат имеет тип long. В этом случае также необходимо применить приведение типа:
(long)(huge_ptr1—huge_ptr2)
Работая в некоторой стандартной модели памяти, программист может в той или иной мере модифицировать ее, применяя в объявлениях модификаторы 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.