6.3.7. Модель пам’яті HUGE
Модель пам’яті HUGE дає
можливість використовувати в програмі статичні дані загальним об’ємом більше
64К байт. Завдяки механізму нормалізації
покажчиків на дані можна, використовуючи покажчик або індексацію,
здійснювати доступ до блоку пам’яті як до масивів, розмір яких більше 64К байт.
(проте це не означає, що окрема функція може описати більше 64К байт даних).
Покажчик зберігається в пам’яті та вступає в операції адресної арифметики в
такому вигляді, що максимально можливе значення записується в сегментну частину
покажчика, а мінімально можливе - в зміщення. Усі операції адресної арифметики
виконуються за спеціальними внутрішніми процедурами, автоматично нормалізуючими покажчик. наприклад, фізична адреса пам’яті
00418h має в моделі HUGE єдине представлення - 0041:0008h. В моделі LARGE така
однозначність відсутня, а при виконанні арифметичних операцій з покажчиками їх
нормалізація не відбувається. В цьому криється причина багатьох важковловимих помилок програмування (див. першу книгу
комплексу). Одна з них полягає в некоректному виконанні операцій порівняння
покажчиків. Наприклад, нехай описані й ініціалізовані
три покажчики:
char far * ptr1 - Oxb8OOOOOOL:
char far * pfr2 - Oxb4004000L;
char far * ptr3 - OxbOOO8OOOL;
Вони
відповідають одній і тій же фізичній адресі ОхЬ8000. Проте операція = = порівняння покажчиків завжди дасть
значення ЛОЖЬ. При
виконанні порівняння far-покажчиків операціями >=, >, <=, <
використовуються тільки зміщення, тобто молодші слова покажчиків у форматі unsigned. Тому, наприклад, ptr1 < ptr2 дає значення ИСТИНА, a ptr2 >= ptr3
- ЛОЖЬ. порівняння
ж far-покажчиків операціями != та = виконується як порівняння чисел long unsigned, а не значень
фізичних адрес.
Інша розповсюджена помилка використання покажчиків, в тому
числі й far-покажчиків, відома в програмуванні як "перескакування сегмента" (segment round wrapping). Якщо до
покажчика додається якесь число, змінюється тільки значення зміщення. Якщо при
цьому отримане значення зміщення повинно перевищити FFFFh,
"перенесення" в значенні сегмента не відбувається, а зміщення
"перестрибує" на границю 0000. представимо ситуацію збільшення на 17h
значення покажчика типу char far
*. Якщо значення покажчика було OFFF:0006h, буде отримано коректне значення
нової адреси - OFFF:001Eh. Проте якщо перед додаванням значення покажчика було
представлене у вигляді 0000:FFF6h, що відповідає тій же самій фізичній адресі,
додавання покажчика з 17h дає некоректний результат - 0000:001Eh. Нормалізовані
покажчики позбавляють програму від можливості таких важковловимих
помилок, оскільки покажчик завжди буде нормалізуватися, що гарантує коректність
операції адресної арифметики. Тому, послідовно нарощуючи far-покажчик, програма
може здійснювати доступ до даних, розмір яких перевищує 64К байт. Проте
використання процедур нормалізації в багато разів уповільнює програму (див.
приклади L6_8.C й L6_9.C в першій книзі комплексу).
![]() |
![]() |
![]() |