Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

ПРИЛОЖЕНИЕ В. Работа с моделями памяти QUICK-C.

В пакете Quick-C вы можете управлять использованием памяти вашей программой, посредством определения для программы моделей памяти. Обычно определять модели памяти не требуется, за исключением следующих случаев: -Программа, компилируемая в среде Quick-C имеет данные типа STATIC, занимающие больше 64К.

-Программа, компилируемая с помощью команды QCL имеет код, превышающий 64К и данные типа STATIC, превышающие 64К.

В данных случаях вы имеете следующие возможности:

1.Если вы выполняете компиляцию с помощью команды QCL, вы можете выбрать одну из стандартных моделей памяти (средняя, компактная или большая), используя опции /A.

2.Можно создать программу, использующую смешанную модель памяти, применяя ключевые слова near и far.

3.Можно объединить метод 2 и метод 1.

В.1 "Ближняя" и "дальняя" адресация.

Термины "near" и "far" (ближний и дальний)-являются решающими в понимании концепции моделей памяти. Данные термины обозначают, каким образом осуществляется доступ к данным в сегментной архитектуре семейства микропроцессоров 8086 (8086, 80186, 80286).

Операционная система DOS загружает код и данные, распределенные вашей программой в сегменты (физическую память). Каждый сегмент имеет длину 64К. Поскольку для программного кода и данных всегда выделяются разные сегменты, минимальное число сегментов, выделенных для программы, это два. Поскольку эти два сегмента требуются каждой программе, они называются стандартными (используемыми по умолчанию). Малая модель памяти использует только два этих сегмента. Остальные модели памяти, описанные в данной Главе, используют либо более одного сегмента кода, либо более одного сегмента данных, либо и то, и другое.

В семействе микропроцессоров 8086, адресация памяти состоит из двух частей:

1.16-ти битовое число, представляющее собой базовый адрес сегмента памяти.

2.Второе 16-битовое число, которое задает смещение в пределах данного сегмента.

Архитектура микропроцессора 8086 такова, что доступ к данным в стандартном сегменте кода или данных осуществляется посредством 16-битового значения смещения. Это возможно, поскольку адреса стандартных сегментов всегда известны. Данное 16-разрядное смещение и называется "ближний" адрес; к нему можно обратиться с помощью "короткого" указателя. Так как для доступа к "ближней" памяти требуется только 16-разрядная арифметика, "короткие" ссылки на код или данные всегда меньше и более эффективны.

Когда данные или код лежат вне стандартных сегментов, адрес должен использовать как значение сегмента, так и значение смещения. Такие адреса называются "дальними" адресами; в программе СИ к таким адресам обращаться можно с помощью "длинных" указателей. Доступ к данным, которые можно назвать "дальними", стоит дороже, в смысле размера и скорости программ, зато это средство позволяет вам адресовать всю память, а не только часть в 64К. Оставшаяся часть данной Главы рассматривает различные методы, которые вы можете использовать для управления в вашей программе "ближней" и "дальней" адресацией.

В.2. Использование стандартных моделей памяти.

Библиотеки, построенные с помощью программы SETUP поддерживают четыре стандартных модели памяти. Использование стандартных моделей памяти-это простейший способ управлять доступом к данным вашей программы.

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

Основным преимуществом использования стандартных моделей памяти для ваших программ является простота. В стандартных моделях памяти, управление памятью задается посредством опций компилятора; поскольку стандартные модели не требуют использование расширенных ключевых слов, они являются лучшим средством писать программный код, переносимый на другие системы (определенные системы, которые не применяют сегментную архитектуру).

Недостатком в использовании стандартных моделей памяти является исключетельно то, что с их помощью можно получить не самый эффективный код. Например, если вы имеете программу средней модели памяти, содержащую большой массив, из-за которого ваша программа занимает память, превышающую 64К-предел для средней модели памяти, было бы лучше объявить один массив с ключевымс словом "far", в то время, как остальная программа будет храниться в средней модели памяти, в противоположность использованию компактной модели для всей программы. Чтобы получить максимальную гибкость и управлять процессом использования памяти вашей программой, вы можете объединить метод стандартных моделей памяти с ключевыми словами near и far, описанными в Разделе В.3. Чтобы во время компиляции задать одну из четырех стандартных моделей памяти (малую, среднюю, компактную или большую) можно использовать опцию /А команды QCL. Данные опции моделей памяти рассматриваются в следующих четырех разделах.


Примечание:

В следующих разделах, которые описывают адресные преобразования для различных моделей памяти, очень важно помнить о двух общих особенностях всех пяти моделей:

1. Ни один исходный модуль не может сгенерировать 64К или больше кода.

2. Ни один элемент данных не может превышать 64К.


В.2.1. Создание программ для малой модели памяти. -Опция:

    /AS

Опция малой модели памяти требует, чтобы компилятор создал программу, занимающую два стандартных сегмента-один для кода и один для данных. Программы малой модели памяти-это обычно СИ-программы, небольшие по размеру, либо имеющие ограниченные цели. Поскольку размеры кода или данных для программ ограничены 64К, общий размер программы для малой модели памяти не может превышать 128К. Большинство программ легко умещаются в данную модель.

По умолчанию, как к коду, так и к данным программ малой модели памяти доступ осуществляется через "ближние" адреса. Вы можете отменить такой подход посредством использования ключевого слова "far". Если вы явно не определите модель памяти, команда QCL автоматически создает программы для малой модели памяти. То есть опция /AS обеспечивается автоматически, вам нет необходимости задавать ее явно.

На рисунке В.1 показано, как распределяется память в малой модели. Рисунок В.1. Карта распределения памяти для малой модели.

Старшие адреса

      Динамическая об-   нераспределенная область для динамического
      ласть (Heap)       распределения

      Стек (STACK)       локальные данные

    _BSS, c_common       Неинициализированные глобальные и статисти-
                         тические данные.

      CONST              данные с доступом только на чтение, сгенери-
                         рованные компилятором.

      _DATA              стандартный сегмент данных (проинициализиро-
                         ванные глобальные и статистические данные)

      NULL               контроль над присвоением нулевого указателя.
       TEXT              сегмент кода для всех модулей

Младшие адреса

В.2.2. Создание программ для средней модели памяти.

-Опция:

    /AM

Опция средней модели памяти распределяет один сегмент для данных и несколько сегментов для программного кода. Каждому исходному модулю отводится свой собственный сегмент кода.

Программы средней модели памяти-это обычно СИ-программы, имеющие большое количество операторов (занимающих больше 64К), но относительно небольшое количество данных (менее 64К). Программный код может занимать большое количество памяти, столько программных сегментов, сколько требуется; в то время как общее количество данных не может быть более 64К. В программах средней модели памяти обеспечивается взаимообмен между скоростью работы и размером программ, поскольку большинство программ чаще обращаются к данным а не к коду.

Поскольку программы, скомпилированные в среде Quick-C всегда используют среднюю модель памяти, данную опцию вам следует задавать в том случае, если вы применяете команду QCL, чтобы скомпилировать модуль для использования в программной среде Quick-C.

На рисунке В.2 показано, как распределяется память для средней модели.

Старшие Динамическая   неиспользованная память, используемая для ди-
адреса  область (Heap) намического распределения.

        STACK          локальные данные

        _BSS c_common  неинициализированные глобальные и статистичес-
                       кие данные.

        CONST          сгенерированные компилчтором данные с досту-

                      пом только на чтение.

        _DATA          стандартный сегмент данных: проинициализирова-
                       нные глобальные и статистические данные

        NULL           контроль на присваивание нулевого указателя

        module TEXT    один сегмент кода на каждый модуль

младшие адреса

В.2.3. Создание программ для компактной модели памяти.

-Опция:

    /AC

При задании компактной модели памяти компилятор создает несколько сегментов для данных, но всего один сегмент для программного кода. Программы компактной модели памяти-это обычно СИ-программы, имеющие большое количество данных, но относительно небольшое число программных операторов. Данные могут занимать любое количество памяти и столько сегментов, сколько требуется.

Стандартно, доступ к элементам кода в программах компактной модели осуществляется посредством "ближних" адресов, а к элементам данных-посредством "дальних" адресов. Данный стандарт вы можете отменить с помощью ключевого слова "near" для данных и ключевого слова "far" для программного кода.

На рисунке В.3 показано, как распределяется память для компактной модели памяти.

Старшие "дальняя"дина- неиспользованная "дальняя" память, применяемая
адреса  мическая об-   для динамического распределения.
        ласть(far heap)

        "ближняя"дина- неиспользованная "ближняя" память, применяемая
        мическая об-   для динамического распределения.
        ласть(near heap)

        STACK          локальные данные

      _BSS и c_common  неинициализированные глобальные и статистичес-
                       кие данные



        CONST          данные с доступом "только-чтение", сгенери-
                       рованные компилятором

        _DATA          стандартный сегмент данных проинициализирован-
                       ные глобальные и статистические данные

        NULL           контроль на присвоение нулевого указателя
        сегмент данных инициализированные и неинициализированные гло-
                       бальные и статистические "дальние" данные

         TEXT          сегмент кода для всех модулей

младшие
адреса

Примечание:

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

void func1(char *dp)
{
.
.
.
}
void func2(char (*fp)(void))
{


.
.
.
}
main()
{
func1(NULL);
func2(NULL);
}
В данном примере обеим функциям func1 и func2 передается 16-разрядный указатель при компиляции в средней модели памяти, и 32-разрядный указатель при компиляции в компактной модели, если не будут в начале программы добавление прототипы, обозначающие типы данных, либо не будет использовано явное приведение типов в аргументе функции func1 (компактная модель), либо func2(средняя модель).


В.2.4 Создание программ для большой модели памяти.

-Опция:

    /AL

При заданной опции большой модели памяти компилятор создает несколько сегментов (столько, сколько требуется) как для кода, так и для данных.

Программа для большой модели памяти-это обычно программы на языке СИ, имеющие очень большой размер программного кода и использующие большое количество данных.

Стандартно, в программах большой модели памяти доступ к коду или данным осуществляется посредством "дальних" адресов. Отменить данный стандарт вы можете с помощью использования ключевого слова "near". На рисунке В.4 показано распределение памяти большой модели.

Старшие "дальняя"дина- неиспользованная "дальняя" память, применяемая
адреса  мическая об-   для динамического распределения.
        ласть(far heap)

        "ближняя"дина- неиспользованная "ближняя" память, применяемая
        мическая об-   для динамического распределения.
        ласть(near heap)

        STACK          локальные данные

      _BSS и c_common  неинициализированные глобальные и статистичес-
                       кие данные

        CONST          данные с доступом "только-чтение", сгенери-
                       рованные компилятором

        _DATA          стандартный сегмент данных проинициализирован-
                       ные глобальные и статистические данные

        NULL           контроль на присвоение нулевого указателя

        сегмент данных инициализированные и неинициализированные гло-
                       бальные и статистические "дальние" данные

        module  TEXT   сегмент кода для всех модулей

младшие
адреса

В.3. Применение ключевых слов "near " и "far".

Существует одно ограничение на структуру заранее заданной модели патяти: когда вы изменяете модель памяти, все размеры адресов для кода и данных должны также изменяться. Однако, компилятор Microsoft Quick-C позволяет вам отменить стандартные адресные соглашения для данной модели памяти и установить доступ посредством "коротких" или "длинных" указателей. Это действие выполняется с помощью ключевых слов "near" и "far". Данные специальные модификаторы типа могут быть использованы со стандартной моделью памяти для того, чтобы преодолеть адресные ограничения на определенные элементы кода или данных, либо чтобы оптимизировать доступ к данным элементам, причем без изменения адресных соглашений для программы в целом. В таблице В.1 показано, как использование ключевых слов влияет на адресацию кода или данных, либо указателей на код или данные.

                                                 Таблица В.1.
      Адресация кода или данных, описанных с ключевыми словами
      "near" или "far".

Ключевое Данные                   Функции                 Арифметика

 слово                                                    указателей


near     Распологаются в стандар- Предполагается, что на- Использует
         тном сегменте данных;    ходятся в текущем сег-  16 разря-
         доступ посредством 16-   менте кода; адресуются   дов
         -разрядного адреса (ука- посредством 16-разрядно-
         затели на данные имеют   го адреса (указатели на
         16 разрядов)             функции имеют 16 разрядов)


Ключевое Данные                   Функции                 Арифметика

 слово                                                    указателей


far      Могут распологаться в лю Не обязательно располо- Использует

         бом месте памяти-не обя- жены в текущем сегменте 16 разрядов
         зательно в текущем сег-  кода; адресуются посред-
         менте данных; адресуются ством 32-разрядного адре
         посредством 32-разрядно- са (указатели на функции
         го адреса (указатели на  имеют в длину 32 разряда)
         данные имеют в длину 32
         разряда).

Примечание:

Ключевые слова near и far-не являются стандартной частью языка СИ; Они имеют смысл только в системах, архитектура которых подобна микропроцессору 8086. Имейте это в виду, если вы собираетесь переносить ваш программный код на другие системы.


В компиляторе Microsoft Quick-C ключевые слова near и far являются стандартными. Для того, чтобы данные ключевые слова трактовались, как обчные идентификаторы, вам следует выполнить одно из следующих действий. -Если вы компилируете программы в среде Quick-C, выполняйте компиляцию с выключенной опцией Language Extensions.

-Если вы компилируете программы с помощью команды QCL, задайте в процессе компиляции опцию /Za.

Данные опции могут оказаться полезны, если вы компилируете программы с помощью компиляторов, в которых near и far не являются ключевыми словами-например, если вы переносите программу, в которой одно из данных слов используется в качестве метки. о том, как использовать опции Language Extension и /Za, смотрите Раздел 8.1.4.6 "Использование расширений к языку СИ фирмы Microsoft: Опция Language Extensions."

В.3.1. Поддержка библиотек для ключевых слов near и far.

Если вы применяете ключевые слова near и far для модификации адресных соглашений отдельных элементов вам можно с вашей программой использовать одну из стандартных библиотек (малую, компактную, среднюю или большую). Однако, вы должны быть осторожны при вызове библиотечных процедур. Обычно, вам нельзя передавать "длинные" указатели, либо адреса на "дальние" элементы данных библиотечным процедурам малой модели памяти. (Исключениями к данному положению являются библиотечные процедуры halloc и hfree, а также семейство функций printf). Но конечно, вы всегда сможете передать значение "дальнего" элемента библиотечной процедуре малой модели. Например:

long far_time val;

time (&time_val); /* некорректно */

printf("%ld\n", time_val); /* корректно */

Если вы используете ключевые слова near и far, мы настоятельно рекомендуем вам применять прототипы функций со списками типов аргументов-для гарантии того, что все аргументы-указатели будут корректно передаваться функциям. Подробности вы найдете в Разделе В.3.4 "Преобразования указателя".

В.3.2. Описание данных с типом near и far.

Ключевые слова near и far модифицируют либо объекты, либо указатели на объекты. При использовании их для описания данных или кода (кода указателей на данные или код), помните о следующих правилах: -Ключевое слово всегда оказывает влияние на объект или указа- тель, находящийся непосредственно справа. В сложных описа- ниях, ключевое слово far и элемент, находящийся непосредстве- нно справа, считается одной единицей. Например, в описании
      char far* *p;

p-это указатель (размер которого зависит от заданной модели па- мяти) на длинный указатель на данные типа char. Полные правила использования специальных ключевых слов в сложных описани- ях смотрите в документе "Microsoft C Language Reference" (Справочное руководство по языку СИ фирмы Microsoft). -Если элемент, находящийся непосредственно справа от ключевого слова, является идентификатором, ключевое слово определяет либо элемент, размещаемый в стандартном сегменте данных (near), либо в отдельном сегменте данных (far). Например:

      char near a;

а размещается в качестве элемента типа char с "ближним" адресом -Если элемент, находящийся непосредственно справа от ключевого слова,является указателем, ключевое слово определяет, будет ли указатель содержать "ближний" адрес (16 разрядов), либо "даль- ний" адрес (32 разрада). Например:

      char far *p;

p размещается, как "длинный" указатель (32 разряда) на элемент типа char.

-Ключевое слово far нальзя использовать для описания данных в программах, функционирующих в среде Quick-C. Однако, его можно использовать для описания указателей на данные. Например, за- пись

      int far item;

для программ, работающих в программной среде, является некорре- ктной, а запись:

      int far *item;

является корректной.

Примеры:

В примерах данного раздела показаны описания данных, использующие ключевые слова near и far.

char a[3000]; /* программа для малой модели памяти */
char far b[3000];
Первое описание в данном примере размещает массив a в стандартном сегменте данных. В противоположность этому, массив b во втором описании может быть размещен в любом "дальнем" сегменте данных. Поскольку данные описания находятся в программе для малой модели памяти, массив a, вероятно представляет собой часто используемые данные, которые для более быстрого доступа помещаются в стандартный сегмент данных. Массив b, скорее всего представляет собой редко используемые данные, которые, могут привести к тому, что размеры стандартного сегмента данных превысят 64К и могут вынудить программиста использовать большую модель памяти, если массив не описан с ключевым словом far. Второе описание использует большой массив, поскольку наиболее вероятно, что программисту понадобится оопределить размещение в памяти для элементов значительного размера.

char a[3000]; /* программа для большой  */
char near b[3000]; /* модели памяти */
В приведенном выше примере, вероятно, скорость доступа для массива a не будет верной. Даже, хотя массив может быть размещен, или не размещен в стандартном сегменте данных, доступ к нему будет осуществляться по 32-разрядному адресу. Массив b явно описан, как near. Это увеличит скорость доступа в данной модели памяти (большой).

char *pa; /* программа для малой */
char far *pb; /* модели памяти */
В приведенном выше примере указатель pa описан, как "короткий" на элемент данных типа char. Указатель является коротким по умолчанию, поскольку данный пример работает в малой модели памяти. В противоположность этому, pb описан, как длинный указатель на элемент типа char; в этом случае pb может быть использован в качестве указателя на массив символов, хранящийся в сегменте, отличном от стандартного сегмента данных. Например, pa можно использовать в качестве указателя на массив a из первого примера, а pb-может быть указателем на массив b.
char far * *pa; /* программа для малой модели памяти */
char far * *pa; /* программа для большой модели памяти */
В данном примере описание указателя иллюстрирует взаимосвязь между выбранной моделью памяти и ключевыми словами far и near. Хотя описания для pa идентичны, в малой модели памяти pa будет описан, как короткий указатель на массив длинных указателей типа char, в то время, как в большой модели памяти, pa будет описан, как длинный указатель на массив длинных указателей типа char.

    char far *near *pb; /* любая модель */
В приведенном выше примере в первом описании pb описываются, как короткий указатель на массив длинных указателей типа char; во втором описании, pb описан, как длинный указатель на массив длинных указателей типа char. Обратите внимание, что в данном примере ключевые слова far и near отменяют адресные соглашения для данной модели памяти, показанные в предыдущем примере; описания для pb будут иметь то же самое действие, независимо от модели памяти.

В.3.3. Описания функций с ключевыми словами near и far.

Правила использования ключевых слов near и far для функций аналогичны использованию этих ключевых слов для данных, что вы увидите из следующих правил:

-Ключевое слово всегда оказывает действие на функцию или ука- затель, находящиеся непосредственно справа. Смотрите Раздел 4.3.3. "Описание с помощью специальных ключевых слов" в доку- менте "Microsoft CLanguage Reference" (Справочное руководство по языку СИ фирмы Microsoft), в котором вы найдете подробные правила использования комплексных объявлений.

-Если описываемый элемент справа от ключевого слова является функцией, то ключевое слово определяет, каким образом будет распределяться память для данной функции ("ближняя" или "даль- няя"). Например, строка:

char far fun ();

определяет fun как функцию, вызываемую по 32-разрядному адресу и возвращающую тип char.

-Если описываемый элемент находящийся непосредственно справа от ключевого слова-это указатель на функцию, то данное ключевое слово определяет, будет функция вызываться по ближнему (16-раз- рядному) или дальнему (32-разрядному) адресу. Например, строка: char (far *pfun)();

определяет pfun, как длинный указатель (32 разряда) на функцию, возвращающую тип char.

-Описания функций должны соответствовать определениям функций. Примеры:

void char far fun(void); /* малая модель */


void char far fun (void)
        {
        .
        .
        .
        }
В приведенном выше примере, fun описана, как функция, возвращающая тип char. Ключевое слово far в описании означает, что функция fun может быть вызвана по 32-разрядному вызову.

static char far * near fun( ); /* большая модель */
static char far * near fun( )
        {
        .
        .
        .
        }
В приведенном выше примере программы для большой модели памяти функция fun описана, как "ближняя" функция, возвращающяя "длинный" указатель на тип char. Такая функция в программе большой модели памяти может быть использована в качестве часто вызываемой вспомогательной процедуры, но только процедурами в ее собственном модуле. Поскольку все процедуры данного модуля находятся в одном и том же кодовом сегменте, доступ к функции всегда может быть организован с помощью "ближнего" вызова. Однако, указатель на fun нельзя передавать в качестве аргумента другой функции вне модуля, в котором функция fun описана.

void far *fun(void); /* малая модель */
void (far *pfun) ( = = fun;
В приведенном выше примере для малой модели памяти pfun определяется как длинный указатель на функцию, имеющую тип возвращаемого значения void, и затем адрес fun присваивается pfun. Фактически, pfun можно использовать в качестве указателя на любую функцию, доступ к которой получается посредством "ближнего" вызова. Обратите внимание, что если функция, адресуемая с помощью pfun не была описана с ключевым словом far, либо она не является far по умолчанию, то вызов функции с помощью pfun приведет к ошибке.

double far * (far fun=) =; /*компактная модель */
double far * (far *pfun)( ) = fun;
Последний пример описывает pfun в качестве "длинного" указателя на функцию, которая возвращает "длинный" указатель типа double, а затем присваивает адрес fun pfun. Данные строки могут быть использованы в программах компактной модели памяти для функций, вызываемых не очень часто, и таким образом, которые могут не находиться в стандартном сегменте кода. Как функция, так и указатель на функцию должны быть описаны с ключевым словом far.

В.3.4. Преобразование указателей.

Передача указателей в качестве аргументов функций может привести к автоматическому преобразованию указателя-аргумента, поскольку передача указателя функции приводит размер указателя к большему из следующих двух размеров:

-Стандартный размер указателя для данного типа, определяемый моделью памяти, используемой в процессе компиляции.

Например, в программах средней модели памяти, аргументы-ука- затели на данные являются стандартно "короткими", а аргументы- -указатели на код являются по умолчанию "длинными".

-Тип аргумента.

Если прототип функции задан с типами аргументов, компилятор выполняет контроль на типы и производит преобразование действительных аргументов к описанному типу соответствующего формального аргумента. Однако, если описание отсутствует, либо список типов аргументов пуст, компилятор автоматически преобразует указатели-аргументы либо к стандартному типу, либо к типу аргумента, в зависимости от того, что больше. Чтобы избежать несоответствия аргументов, вам следует всегда использовать прототип, имеющий типы аргуметов.

Примеры:

/* данная программа в компактной или большой модели памяти приводит
** к неожиданным результатам */
*/
main( )
       {
        int near *x
        char far *y;
        int z = 1;
        test_fun (x, y, z); /* преобразуется к длинному указателю */
        }
int test_fun(ptr1, ptr2, a)
        int near *ptr1;


        char far *ptr2;
        int a;
        {
        printf("Value of a = %d\n", a);
        }
Если предшествующий пример компилируется в малой модели памяти (с опцией /AS в командной строке QCL) или в средней модели памяти (либо без опций модели памяти, либо с опцией /AM в командной строке QCL), размер аргумента-указателя х-16 разрядов, размер аргумента-указателя y-32 разряда, и распечатываемое значение a -1. Однако, если предшествующий пример компилируется с опциями /AC или /AL, оба указателя x и y при передаче функции test fun автоматически конвертируются в "длинные" указатели. Поскольку ptr1,первый параметр test fun определен как короткий указатель, он занимает только 16 из передаваемых 32 разрядов. Следующий параметр ptr2 займет оставшиеся 16 разрядов перезаданных ptr1 плюс 16 разрядов из 32 разрядов, передаваемых ему. Наконец, третий параметр, а займет оставшиеся 16 разрядов от ptr2, вместо значения z в функции main. Данный процесс сдвигов не сгенерирует сообщение об ошибке, поскольку как вызов функции, так и определение функции корректны, но в данном слечае программа не будет работать так, как вы предполагали, поскольку значение, присвоенное а будет не тем, какое должно быть Чтобы передать ptr1, как "короткий" указатель вам следует добавить вначале описания, определяющее аргумент функции test fun, как короткий указатель, как показано в следующем примере:

/* во-первых, опишим функцию test_fun таким образом, чтобы
** компилятор заранее знал, что аргумент является коротким указа-
** телем */


*/
int test_fun)int near*, char far *, int);
main( )
        {
        int near *x;
        char far *y;
        int z = 1;
        test_fun(x, y, z); /* теперь, x не будет преобразован к длин-
                           ** ному указателю; он будет передан, как
                           ** короткий указатель, независимо от того,
                           ** какая модель памяти используется
                           */
        }
int test_fun(ptr1, ptr2, a)
        int near *ptr1;
        char far *ptr2;
        int a;
        {
        printf ("Value of a = %d\n", a);
        }
Заметим, что перестановка порядка определений для функции test fun и main в первом примере не поможет избежать преобразований указателя; аргументы-указатели должны быть описаны первый раз, как во втором примере.

В.4. Установка порога данных.

-Опция:

/GT[number]

По умолчанию, в малой и средней моделях памяти компилятор размещает все глобальные и статистические данные в стандартном сегменте данных. В компактной и большой модели памяти в стандартном сегменте данных размещаются только проинициализированные статические и глобальные данные. При заданной опции /GT все элементы данных, размер которых превышает number байтов, будут размещаться в новом сегменте данных. Если число number задано, оно должно непосредственно следовать за опцией /GT, без разделяющих пробелов. Если число number опущено, пороговым числом по умолчанию будет 256. Если же опущена опция /GT, пороговое значение равно 32767.

Опцию /GT можно использовать только с программами компактной и большой модели, поскольку программы малой и средней модели имеют только один сегмент данных. Данная опция бывает полезна, если программы, имеют более 64К проинициализированных статических и глобальных данных, распределенных на малые элементы.

В.5.Наименование текстового сегмента.

-Опция:

    /NTtextsegment

Сегментом является последовательный блок двоичной информации (код или данные), полученный после работы компилятора Microsoft Quick-C. Каждый модуль (то есть каждый объектный файл, созданный компилятором) имеет, по крайней мере, 2 сегмента: текстовый сегмент, содержащий программные инструкции, и сегмент данных, содержащий программные данные. Каждый сегмент в каждом модуле имеет имя. Компановщик использует данное имя для определения порядка, в котором программные сегменты располагаются в памяти при загрузке программы для выполнения. (Обратите внимание, что сегменты группы, называемой DGROUP, являются исключением). Имена текстового сегмента и сегмента данных обычно создаются компилятором Quick-C. В программах средней модели памяти текст каждого модуля размещается в отдельном сегменте со своим именем, получаемым из имени базового модуля с суффиксом TEXT. Сегмент данных получает имя DATA.

Стандартное имя текстового сегмента вы можете отменить с помощью опции /NT компилятора Quick-C ("name text"), таким образом изменяя стандартный порядок загрузки. Данная опция дает текстовому сегменту каждого компилируемого модуля новое имя.

Аргумент textsegment, используемый опцией /NT, может быть любой комбинацией букв и цифр. Пробел между /NT и textsegment необязателен.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог