рефераты

рефераты

 
 
рефераты рефераты

Меню

Реферат: Turbo C++ Programer`s guide рефераты

if (a == b) . . .

if (b == c) . . .

if (a == c) . . .

Аналогичная проблема возникает, когда вам требуется сравнивать дальние указатели при помощи операций >, >=, < и <=. В этих случаях в сравнении участвует только смещение (как unsigned); при указанных выше значениях a, b и cследующие выражения дадут значения "истина":

if (a > b) . . .

if (b > c) . . .

if (a > c) . . .

Операции равенства (==) и неравенства (!=) используют 32-битовые значения как unsigned long (а не в виде полного адреса памяти). Операции сравнения(<=, >=, < и >) используют только смещение.

Операции== и != требуют все 32 бита, что позволяет компьютеру выполнять сравнение с пустым (NULL) указателем (0000:0000). Если дляпроверки равенства использовалось только значение смещения, то любой указатель со смещением 0000 будет равен пустому указателю, что явно несовпадает с тем, что вы хотели получить.

Важное замечание

При сложении некоторого значения сдальним указателем изменяется только смещение. Если слагаемое настолько велико, что сумма превышает FFFF (максимально возможная для смещения величина), то указатель перейдет снова к началу сегмента. Например, если сложить 1 и 5031:FFFF, то результат будет равен 5031:0000 (а не 6031:0000). Подобным же образом, при вычитании 1 из 5031:0000 получится 5031:FFFF (а не 5030:000F).

Если вам понадобится выполнить сравнение указателей, то безопасный способ состоит в том, чтобы либо использовать для этого ближние указатели -все содним адресомсегмента - либо описываемые ниже указатели huge.

Указатели huge

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

Что такое нормализованный указатель? Это 32-битовый указатель, который содержитв своем адресе сегмента максимально возможное там значение. Поскольку сегмент может начинаться через каждые 16 байт (10 при основании 16), это означает, что величина смещения будет равна числу от 0 до 15 (от 0 до F с основанием 16).

Для нормализации указателя он преобразуется к20-битовому адресу, после чего правые 4 бита берутся в качестве смещения, а левые 16 битов - как адрес сегмента. Например, указатель 2F84:0532 можно сначала преобразовать к абсолютному адресу 2FD72, после чего получить нормализованный указатель2FD7:0002. Приведемеще ннесколько указателей с нормализованными значениями:

0000:01230012:0003

0040:00560045:0006

500D:9407594D:0007

7418:D03F811B:000F

Существует три причины, заставляющие всегда хранить указатель huge в нормализованном виде:

1. Поскольку в таком случае любому заданному адресу памяти соответствует только один возможный адрес в виде сегмент:смещение типа huge. Это означает, что для указателей huge операции == и != всегда будут возвращать правильное значение.

2. Кроме того, операции >, >=, < и <= работают с полным 32-битовым значением указателя huge. Нормализация гарантирует в данном случае корректность результата.

3. И наконец, вследствие нормализации смещение в указателе huge выполняет автоматический переход через 16 но вотличие от дальних указателей, переход затрагивает и сегмент. Например, при инкременте 811B:000Fрезультатбудет равен 811C: 0000; аналогичным образом, при декременте 800C:0000 получится 811B:000F. Эта особенность указателей huge позволяет манипулировать соструктурами данных сразмером более 64К. Гарантируется, например, что если у вас имеется массив структур типа huge, превышающий 64К, индексация этого массива и выбор поля структуры всегда будут выполняться правильно, независимо от размера структуры.

Использование указателей huge имеет свою цену: увеличение времени обработки. Арифметические операции с указателями huge выполняются при помощи обращений к специальным подпрограммам. Вследствие этого арифметические вычисления занимаютсущественно больше времени по сравнению с вычислениями для указателей far или near.

Шесть моделей памяти

Turbo C++ работает с шестью моделями памяти: tiny, small, medium, compact, large и huge. выбор модели памяти определяется требованиями вашей программы.Ниже приводятся краткие описания каждой из них:

Tiny

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

Как вы уже поняли, это минимальная из моделей памяти.Все четыре сегментных регистра (CS, DS, SS и ES) устанавливаются на один и тот же адрес, что дает общий размер кода, данных и стека, равный 64К. Используютсяисключительноближние указатели. Программы с моделью памяти tuny могут быть преобразованы к формату .COM при компоновке с опцией /t.

Small

Эта модель хорошо подходит для небольших прикладных программ.

Сегменты кода и данных расположены отдельно друг от друга и не перекрываются, что позволяет иметь 64К кода программы и 64К данных и стека. Используются только ближние указатели.

Medium

Годится для больших программ,для которых не требуется держать в памяти большой объем данных.

Для кода, но не для данных используются дальние указатели. В результате данные плюс стек ограничены размером 64К, а код может занимать до 1 Мб.

Compact

Лучше всего использовать в тех случаях, когда размер кода невелик, но требуется адресация большого объема данных.

Ситуация, противоположная относительно модели Medium: дальние указатели используются для данных, но не для кода. Следовательно, код здесь ограничен 64К, а предельный размер данных - 1 Мб.

Large

Модели large иhuge применяются только в очень больших программах.

Дальние указатели используются как для кода,так идля данных, что дает предельный размер 1 Мб для обоих.

Huge

Дальние указатели используютсякак для кода, так и для данных. Turbo C++ обычно ограничиваетразмерстатических данных 64К;модельпамятиhuge отменяетэто ограничение, позволяя статическим данным занимать более 64К.

Для выбора любойиз этих моделей памяти вы должны либо воспользоваться соответствующей опцией меню интегрированной среды, либо ввести опцию при запуске компилятора командной строки.

Следующие иллюстрации(Рис.4.3 - 4.8) показывают,как выполняется распределение памяти для всех шести моделей памяти Turbo C++.

Сегментные регистры:   Размер сегмента:

Младший ^ CS,DS,SS-----> --------------------------- адрес | / \! _TEXT класс 'CODE' \! \

| |  \!код                          \! |

| |  \!-------------------------\! |

| |  \! _DATA класс 'DATA'   \! |

| |  \!инициализированные данные\! |

| |  \!-------------------------\! |

| |  \! _BSS класс 'BSS'                                 \! |

|DGROUP/   \!неинициализирован. данные\!  \ до 64К

|\          \!-------------------------\!  /

| |          \!  куча|      \! |

| |          \!v      \! |

| |          \!-------------------------\! |  Свободная

| |          \!                         \!-|--область

|SP(TOS)--|->\!-------------------------\! |  памяти

| |  \!^                         \! |

Старший |  \ \!  стек|                                 \!/

адрес  v  Начало SP----> ---------------------------

Рис.4.3  Сегментация для модели памяти tiny

Сегментные регистры:   Размер сегмента:

Младший ^ CS-----------> --------------------------- адрес | \! _TEXT класс 'CODE' \!

|           \!код                  \!  до 64К

|  DS,SS--------> \!-------------------------\!

|  / \! _DATA класс 'DATA'   \!\

| |  \!инициализированные данные\! |

| |  \!-------------------------\! |

| |  \! _BSS класс 'BSS'     \! |

|DGROUP/   \!неинициализирован. данные\!  \ до 64К

|\          \!-------------------------\!  /

| |          \!  куча|      \! |

| |          \!v      \! |

| |          \!-------------------------\! |  Свободная

| |          \!                         \!-|--область

|SP(TOS)--|->\!-------------------------\! |  памяти

| |  \!^                         \! |

|  \ \!  стек|                               \!/

|  Начало SP----->\!--------------------------

|           \!  дальняя|                         \! До конца

|           \!  кучаv                      \! памяти

|           \!-------------------------\!                                           Свободная

Старший |              \!                         \!----область

адрес  v                ---------------------------                                         памяти

Рис.4.4  Сегментация для модели памяти small

Сегментные регистры:                       Размер сегмента:

Младший ^           ---------------------------

адрес  |                 \!            _TEXT класс 'CODE'\!  до 64К

|           \! sfileкод                         \!каждый sfile

|  DS,SS--------> \!---/---------------------\!

|  / \!  / _DATA класс 'DATA'   \!\

|  Несколько __|__\!_/инициализирован. данные\! |

|  --------- |  \!-------------------------\! |

|  \!sfile A\! |  \! _BSS класс 'BSS'                                               \! |

CS->\!sfile B\! | \!неинициализирован. данные\! \ до 64К | \! \! | \!-------------------------\! /

|  \!sfile Z\! |  \!  куча|                                             \! |

|  --------- |  \!v                                      \! |

|DGROUP/   \!-------------------------\! |  Свободная

|\   \!                         \!-|--область

|SP(TOS)--|->\!-------------------------\! |  памяти

| |  \!^                         \! |

|  \ \!  стек|                               \!/

|  Начало SP----->\!--------------------------

|           \!  дальняя|                         \! До конца

|           \!  кучаv                      \! памяти

|           \!-------------------------\!                                           Свободная

Старший |              \!                         \!----область

адрес  v                ---------------------------                                         памяти

Рис.4.5  Сегментация для модели памяти medium

CS указывает одновременно только на один sfile.

Сегментные регистры:   Размер сегмента:

Младший ^ CS-----------> --------------------------- адрес | \! _TEXT класс 'CODE' \!

|           \!код                  \!  до 64К

|  DS ----------> \!-------------------------\!

|  / \! _DATA класс 'DATA'   \!\

| |  \!инициализированные данные\! |

|DGROUP/   \!-------------------------\!  \ до 64К

|\   \! _BSS класс 'BSS'                                \!  /

| |  \!неинициализирован. данные\! |

|  \ \!                        \!/

|  SS --------->  \!-------------------------\!  Свободная

|           \!                         \!----область

|SP(TOS)---->\!-------------------------\!                                                             памяти

|           \!^                 \!

|           \!  стек|                        \! до 64К

|  Начало SP----->\!--------------------------

|           \!  куча|                       \! До конца

|           \!v                 \! памяти

|           \!-------------------------\!                                           Свободная

Старший |              \!                         \!----область

адрес  v                ---------------------------                                         памяти

Рис.4.6  Сегментация для модели памяти compact

Несколько

\!sfile A\!

CS->\!sfile B\!

\!               \!

\!sfile Z\!<---

---------  \

\

\

\

\

Сегментные регистры:   \                             Размер сегмента:

Младший ^           ----\----------------------

адрес  |                 \! \  _TEXT класс 'CODE'\!  до 64К

|           \! sfileкод                         \!каждый sfile

|  DS ----------> \!-------------------------\!

|  / \! _DATA класс 'DATA'   \!\

| |  \!  инициализирован. данные\! |

|DGROUP/   \!-------------------------\!  \ до 64К

|\   \! _BSS класс 'BSS'                                \!  /

| |  \!неинициализирован. данные\! |

|  \ \!                        \!/

|  SS --------->  \!-------------------------\!  Свободная

|           \!                         \!----область

|SP(TOS)---->\!-------------------------\!                                                             памяти

|           \!^                 \!

|           \!  стек|                        \! до 64К

|  Начало SP----->\!--------------------------

|           \!  куча|                       \! До конца

|           \!v                 \! памяти

|           \!-------------------------\!                                           Свободная

Старший |              \!                         \!----область

адрес  v                ---------------------------                                         памяти

Рис.4.7  Сегментация для модели памяти large

Несколько

\!sfile A\!

CS->\!sfile B\!

\!               \!

\!sfile Z\!<---

---------  \

\

\

\

\

Сегментные регистры:   \                             Размер сегмента:

Младший ^           ----\----------------------

адрес  |                 \! \  _TEXT класс 'CODE'\!  до 64К

|           \! sfileкод                         \!каждый sfile

|           \!-------------------------\!

| Несколько  \!                        \!

| ---------  \!                               \!

| \!sfile A\!  \!                                \!

|  DS->\!sfile B\!<-\!sfile _DATA класс 'DATA' \!   до 64К

| \! \!  \!неинициализирован. данные\! каждый sfile

| \!sfile Z\!  \!                                  \!

|  SS --------->  \!-------------------------\!  Свободная

|           \!                         \!----область

|SP(TOS)---->\!-------------------------\!                                                             памяти

|           \!^                 \!

|           \!  стек|                        \! до 64К

|  Начало SP----->\!--------------------------

|           \!  куча|                       \! До конца

|           \!v                 \! памяти

|           \!-------------------------\!                                           Свободная

Старший |              \!                         \!----область

адрес  v                ---------------------------                                         памяти

Рис.4.8  Сегментация для модели памяти huge

Таблица 4.1. суммирует различные модели, а также результаты их сравнения друг с другом. Эти модели часто группируются в соответствии с тем, насколько малы (64К) или велики (1М) размеры их модулей кода и данных; Эти группы соответствуют рядами колонкам табл. 4.1.

-----------------------------------------------------------

Размер \!                       Размер кода

данных \! ------------------------------------------------- \!   64 K      \!1 Mb

----------------------------------------------------------- \!  Tiny (данные, коды     \!

64K\!  перекрываются                      \!

\!  максимальный размер 64К)  \!

\!               \!

\!   Small (без перекрытия                             \!   Medium (данные - small

\!  максимальный размер 128К) \!   коды - large)

\!               \!

1Mb\! Compact ( данные - large \! Large ( данные и коды \! коды - small) \! large)

\!               \!

\!               \!   Huge  (также как и large,

\!               \!  но cтатические

\!               \!  данные  >64 K )

Важно!

Когда Выкомпилируете модуль (исходный файл с некоторым количеством процедур в нем), то результирующий код для этого модуля не может превышать 64К, т.к. он должен вмещаться в один кодовый сегмент. Это остается правилом, даже если Вы используете один из больших кодовых модулей (medium, large, huge). Если ваши модули очень велики ( > 64К ), Вы должны разбить их на несколько маленьких исходных файлов, компилировать их раздельно, а потом собирать в один файл. Аналогичным образом, несмотря на то, что huge модель позволяет набору статических данных превышать размер 64 К, все равно он должен быть < 64K в каждом модуле.

Программирование с использованием различных моделей памяти: адресные модификаторы

Turbo C++ вводит 8 новых ключевых слов, не имеющихся в стандартном ANSI C ( near, far, huge, _cs, _ds, _es, _ss, _seg), которые могут использоваться в качестве модификаторов адресных указателей (а иногда и функций) с некоторыми ограничениями.

В Turbo C ++ вы можете модифицировать объявления функций и адресных указателей с помощью ключевых слов near, far, huge. Мы уже объяснили смыслуказателей near, far, huge ранее в этой главе. near-функции вызываются near-вызовами с последующим near-выходом из них. Аналогичным образом far-функции вызываются far-вызовами с последующим far-выходом из них. huge-функции аналогичны far-функциям,за исключением того,что huge-функции устанавливают регистр DS в новое значение.

Кроме того имеются четыре специальных near-указателей данных: _cs, _ds, _es, _ss. Это шестнадцатибитовые указатели, которые специально ассоциируются с соответствующими сегментными регистрами, например, если бы вы должны были объявитьуказатель равным:

char _ss *p;

то рсодержал бы в этом случае шестнадцатибитовое смещение в сегменте стека.

Существует некоторое ограничение на использование сегментных указателей:

- Выне можете делать инкремент и декремент с указателями сегментов. Когда выприбавляете или вычитаете целое из сегментного указателя, он автоматически преобразуетсяв far-указатель, а арифметическая операция выполняетсятак, как если бы целое было прибавлено или вычтено из far-указателя.

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40