Приложение A. Замечания по программированию

          В данном приложении приведена основная информация по постро-
     ению программ с конкретными моделями памяти и форматами выполняе-
     мого кода.


Упрощенные директивы определения сегмента

В следующей таблице показаны используемые по умолчанию для каждой модели памяти атрибуты сегмента. Используемые по умолчанию сегменты и типы для модели памяти TINY Таблица A.1 ----------------------------------------------------------------¬ ¦ Директива Имя Выравнивание Комбинирование Класс Группа¦ +---------------------------------------------------------------+ ¦.CODE _TEXT WORD PUBLIC 'CODE' DGROUP ¦ ¦.FARDATA FAR_DATA PARA private 'FAR_DATA' ¦ ¦.FARDATA? FAR_BSS PARA private 'FAR_BSS' ¦ ¦.DATA _DATA WORD PUBLIC 'DATA' DGROUP ¦ ¦.CONST CONST WORD PUBLIC 'CONST; DGROUP ¦ ¦.DATA? _BSS WORD PUBLIC 'BSS' DGROUP ¦ ¦STACK* STACK PARA STACK 'STACK' DGROUP ¦ ¦ ¦ ¦ * - STACK не подразумевается размещенным в DGROUP или¦ ¦FARSTACK, заданным в директиве MODEL. ¦ L---------------------------------------------------------------- Используемые по умолчанию сегменты и типы для модели памяти SMALL Таблица A.2 ----------------------------------------------------------------¬ ¦ Директива Имя Выравнивание Комбинирование Класс Группа¦ +---------------------------------------------------------------+ ¦.CODE _TEXT WORD PUBLIC 'CODE' ¦ ¦.FARDATA FAR_DATA PARA private 'FAR_DATA' ¦ ¦.FARDATA? FAR_BSS PARA private 'FAR_BSS' ¦ ¦.DATA _DATA WORD PUBLIC 'DATA' DGROUP ¦ ¦.CONST CONST WORD PUBLIC 'CONST; DGROUP ¦ ¦.DATA? _BSS WORD PUBLIC 'BSS' DGROUP ¦ ¦STACK* STACK PARA STACK 'STACK' DGROUP ¦ ¦ ¦ ¦ * - STACK не подразумевается размещенным в DGROUP или¦ ¦ FARSTACK, заданным в директиве MODEL. ¦ L---------------------------------------------------------------- Используемые по умолчанию сегменты и типы для модели памяти MEDIUM Таблица A.3 ----------------------------------------------------------------¬ ¦ Директива Имя Выравнивание Комбинирование Класс Группа¦ +---------------------------------------------------------------+ ¦.CODE имя_TEXT WORD PUBLIC 'CODE' ¦ ¦.FARDATA FAR_DATA PARA private 'FAR_DATA' ¦ ¦.FARDATA? FAR_BSS PARA private 'FAR_BSS' ¦ ¦.DATA _DATA WORD PUBLIC 'DATA' DGROUP ¦ ¦.CONST CONST WORD PUBLIC 'CONST; DGROUP ¦ ¦.DATA? _BSS WORD PUBLIC 'BSS' DGROUP ¦ ¦STACK* STACK PARA STACK 'STACK' DGROUP ¦ ¦ ¦ ¦ * - STACK не подразумевается размещенным в DGROUP или ¦ ¦ FARSTACK, заданным в директиве MODEL. ¦ L---------------------------------------------------------------- Используемые по умолчанию сегменты и типы для модели памяти COMPACT Таблица A.4 ----------------------------------------------------------------¬ ¦ Директива Имя Выравнивание Комбинирование Класс Группа¦ +---------------------------------------------------------------+ ¦.CODE _TEXT WORD PUBLIC 'CODE' ¦ ¦.FARDATA FAR_DATA PARA private 'FAR_DATA' ¦ ¦.FARDATA? FAR_BSS PARA private 'FAR_BSS' ¦ ¦.DATA _DATA WORD PUBLIC 'DATA' DGROUP ¦ ¦.CONST CONST WORD PUBLIC 'CONST; DGROUP ¦ ¦.DATA? _BSS WORD PUBLIC 'BSS' DGROUP ¦ ¦STACK* STACK PARA STACK 'STACK' DGROUP ¦ ¦ ¦ ¦ * - STACK не подразумевается размещенным в DGROUP или¦ ¦FARSTACK, заданным в директиве MODEL. ¦ L---------------------------------------------------------------- Используемые по умолчанию сегменты и типы для модели памяти LARGE или HUGE Таблица A.5 ----------------------------------------------------------------¬ ¦ Директива Имя Выравнивание Комбинирование Класс Группа¦ +---------------------------------------------------------------+ ¦.CODE имя_TEXT WORD PUBLIC 'CODE' ¦ ¦.FARDATA FAR_DATA PARA private 'FAR_DATA' ¦ ¦.FARDATA? FAR_BSS PARA private 'FAR_BSS' ¦ ¦.DATA _DATA WORD PUBLIC 'DATA' DGROUP ¦ ¦.CONST CONST WORD PUBLIC 'CONST; DGROUP ¦ ¦.DATA? _BSS WORD PUBLIC 'BSS' DGROUP ¦ ¦STACK* STACK PARA STACK 'STACK' DGROUP ¦ ¦ ¦ ¦ * - STACK не подразумевается размещенным в DGROUP или¦ ¦FARSTACK, заданным в директиве MODEL. ¦ L---------------------------------------------------------------- Используемые по умолчанию сегменты и типы для модели памяти HUGE (TCHUGE) Borland C++ Таблица A.6 ----------------------------------------------------------------¬ ¦ Директива Имя Выравнивание Комбинирование Класс Группа¦ +---------------------------------------------------------------+ ¦.CODE имя_TEXT WORD PUBLIC 'CODE' ¦ ¦.FARDATA FAR_DATA PARA private 'FAR_DATA' ¦ ¦.FARDATA? FAR_BSS PARA private 'FAR_BSS' ¦ ¦.DATA имя_DATA PARA private 'DATA' ¦ ¦STACK* STACK PARA STACK 'STACK' ¦ ¦ ¦ ¦ * - STACK не подразумевается размещенным в DGROUP или¦ ¦FARSTACK, заданным в директиве MODEL. ¦ L----------------------------------------------------------------

Программы DOS

Программы DOS предназначены для работы под управлением опе- рационной системы DOS и записываются в двух форматах: - формат .EXE; - формат .COM. Формат EXE позволяет использовать наиболее общую в DOS сег- ментацию программы. Программы могут иметь насколько сегментов и могут ссылаться на сегмент или группу сегментов по имени. Таким образом, программы .EXE могут превышать по размеру 64К. Формат COM представляет собой достаточно простой формат. Программы в таком формате не могут содержать символьных ссылок на имена групп и сегментов. Таким образом, программы COM обычно пи- шутся с использованием модели TINY и ограничены по размеру данных или кода 64 килобайтами. Чтобы строить программы DOS, вам потребуется компоновщик (например, TLINK) и утилита построения программ (например, MAKE). Подробнее об утилитах рассказывается в Приложении D.

Замечания по программам формата EXE

При загрузке программы EXE операционная система устанавлива- ет регистры следующим образом: ------------------T---------------------------------------------¬ ¦ Регистр ¦ Значение ¦ +-----------------+---------------------------------------------+ ¦ DS, ES ¦ Содержит адрес параграфа для префикса прог- ¦ ¦ ¦ рамного сегмента программы (PSP). PSP со- ¦ ¦ ¦ держит передаваемые программе в командной ¦ ¦ ¦ строке аргументы и указатель на строку опе- ¦ ¦ ¦ рационной среды для программы. ¦ ¦ ¦ ¦ ¦ CS:IP ¦ Содержит начальный адрес, заданный в опера- ¦ ¦ ¦ торе END в одном из модулей программы, или ¦ ¦ ¦ адрес директивы STARTUPCODE. ¦ ¦ ¦ ¦ ¦ SS:SP ¦ Содержит адрес последнего слова, которое ¦ ¦ ¦ задает в программе сегмент стека. ¦ L-----------------+---------------------------------------------- В программах EXE вы можете задавать любую модель памяти. Следует использовать возможно более простую модель, поскольку это обеспечивает более быстрое выполнение и упрощает программирова- ние. Например, если в вашей программе никогда не предполагается использовать более 64К данных и области стека, то вполне можно использовать модель TINY. Директива STURTUPCODE в модуле генерирует инструкции, кото- рые автоматически инициализируют все необходимые регистры, соот- ветствующие выбранной модели. Для использования в программе она сохраняет адрес параграфа PSP в сегменте ES. Когда вы загружаете программу, операционная система выделяет программе до ее завершения всю оставшуюся память. Для программ, которые не используют динамически распределяемую область памяти, или которые строят в памяти свою собственную динамически распре- деляемую область, такое поведение вполне подходит. Другие прог- раммы могут выделять память через DOS. В этом случае через запро- сом на память из DOS память должна быть освобождена и доступна операционной системе. Эти вопросы иллюстрируются примером программы EXEPROG.ASM на дистрибутивном диске. Чтобы сформировать программу EXE, исполь- зуйте утилиту MAKE. В формирующем файле MAKEFILE следует указать все модули, с которыми компонуется программа, например: EXECPROG.EXE: EXECPROG.OBJ TLINK EXECPROG; EXECPROG.OBJ: EXECPROG.ASM TASM EXECPROG

Замечания по программам формата COM

Программы COM представляют собой ограниченные версии прог- рамм EXE. Каждую программу формата COM можно представить как программу EXE, но не каждую программу EXE можно представить как программу формата COM. Здесь действуют следующие ограничения: - Программы COM следует писать с использованием модели TINY. - В программах COM нельзя использовать предопределенный сег- мент стека. - Программа COM не может содержать прямых адресных ссылок на адрес сегмента или группы. Это означает, что программа не может содержать непосредственных дальних вызовов или ссы- латься на сегменты по имени. Все процедуры в программе COM должны описываться как BEAR. - Выполнение должно начинаться со смещения 100h в сегменте кода. Чтобы это произошло, укажите в качестве первой инс- трукции сегмента кода директиву STURTUPCODE. Турбо Ассемблер загружает программы COM, начиная со смещения 100h в префиксе программного сегмента программы (PSP). Для этого директива STARTUPCODE для модели TINY автоматически помещает в программу ORG 100h. При загрузке программы COM устанавливаются следующие регист- ры: --------------------T-------------------------------------------¬ ¦ Регистр ¦ Значение ¦ +-------------------+-------------------------------------------+ ¦ CS,DS,ES,SS ¦ Содержит адрес параграфа в PSP программы. ¦ ¦ ¦ ¦ ¦ IP ¦ Устанавливается в значение 100h. ¦ ¦ ¦ ¦ ¦ SP ¦ Устанавливается в 0FFFEh (последнее слово ¦ ¦ ¦ в сегменте программы. ¦ L-------------------+-------------------------------------------- Если вы не хотите размещать стек в конце сегмента программы, то нужно установить новый стек. Для такого стека используйте неи- нициализированный сегмент данных (UDATASEG). Хотя программы COM должны определяться с моделью памяти TINY, с помощью директив CODESEG, DATASEG и UDATASEG можно разде- лить код данные и неинициализированные данные. Как и в случае программ EXE, когда вы загружаете программу COM, Турбо Ассемблер выделяет для ее завершения всю оставшуюся память. При возврате памяти в DOS убедитесь, что вы не освободи- ли непреднамеренно неинициализированные данные. Данные вопросы иллюстрируются файлом-примером COMPROPG.ASM, который можно найти на дистрибутивных дисках Турбо Ассемблера. Чтобы сформировать программу COM, используйте утилиту MAKE. В формирующем файле MAEKFILE следует указать все модули, с кото- рыми компонуется программа, например: COMPROG.COM: COMPROG.OBJ TLINK COMPROG; COMPROG.OBJ: COMPROG.ASM TASM COMPROG

Программы Windows

Турбо Ассемблер можно использовать для создания прикладных программ Windows. Windows может работать либо в реальном режиме (на всех процессорах 8086) или в защищенном режиме (на процессоре 80286 и старше). Таким образом программа, написанная для Windows, может работать в защищенном режиме. С помощью директив CODESEG, DATASEG и UDATASEG следует аккуратно разделить код и данные и ис- пользовать директиву WARN PRO, чтобы отмечать любые проблемы с доступом, которые могут возникать во время ассемблирования. Нако- нец, в программах защищенного режима не следует пытаться устанав- ливать сегментные регистры в вычисленные значения параграфов сег- мента. Значениями сегментов в защищенном режиме не являются адреса параграфов. Вместо этого используются дескрипторы, которые не имеют смысла в прикладной программе. Кроме Турбо Ассемблера и Турбо отладчика для создания эффек- тивных прикладных программ Windows требуются другие средства. В частности, вы должны располагать компилятором Borland C++ (либо Microsoft C 2.6 и Windows Software Dewelopment Kit). Прикладные программы Windows обычно требуют наличия утилиты-компилятора ре- сурсов (RC) этих пакетов. Должны быть также доступны стандартные библиотеки. В Windows также необходим компоновщик (например, TLINK) и утилита построения программ (например, MAKE). Данное приложение содержит простейшие рекомендации по созда- нию прикладных программ Windows и динамически компонуемых библио- тек (DLL). Более полное описание прикладных программ Windows мож- но найти в "Руководстве пользователя по С++" и соответствующей документации по Windows.

Замечания по динамически компонуемым библиотекам Windows

Динамически компонуемая библиотека (DLL) представляет собой группу процедур, которую вы можете вызывать из прикладных прог- рамм Windows. Библиотеки DLL расширяют интерфейс прикладных прог- рамм Windows. Библиотеки DLL выполняют множество функций. Например, вы мо- жете в DLL неинтерактивные программы DOS. С помощью DLL можно добавить новые средства работы с экраном. На дистрибутивном диске Турбо Ассемблера можно найти пример программы с именем DLLPROG.ASM, который иллюстрирует DLL. Для построения DLL можно использовать утилиту MAKE. Формиру- ющий файл должен включать в себя все модули, которые должны ком- поноваться с DLL, например: dllprog.dll: dllprog.obj dllprog.def TLINK dllprog,,,,dllprog RC dllprog.dll dllprog.obj: dllprog.asm TASM dllprog Данный процесс построения требует наличия следующего файла определений компоновщика DLLPROG.DEF: LIBRARY DLLPROG EXETYPE WINDOWS CODE PRELOAD MOVEABLE DISCARDABLE ; CODE применяется к ; сегментам _TEXT или ; в классе CODE DATA PRELOAD MOVEABLE SINGLE ; DATE применяется ко ; всем сегментам в ; группе DGROUP и в ; классе DATA ; (должен быть ; SINGLE для всех DLL HEAPSIZE 0

Замечания по прикладным программам Windows

Прикладная программа Windows во многом аналогична DLL с единственной процедурой с именем WinMain. Windows вызывает WinMain для запуска процедуры. Прикладная программа имеет обычно стандартную структуру, которая позволяет ей взаимодействовать с графической операционной средой Windows. Пример прикладной программы Windows можно найти в файле WINPROC.ASM на дистрибутивных дисках Турбо Ассемблера. В данном примере для вывода сообщения на экран используются функциональные возможности, обеспечиваемые предыдущим примером DLL. Для построения прикладной программы Wiondows можно использо- вать утилиту MAKE. При этом в формирующем файле следует указать все модули, компонуемые с данной прикладной программой: winproc.exe: winprog.obj winprog.def winprogg.res TLINK winprog,,,,winprog RC winprog.res winproc.res:winproc.rc RC -r winproc.rc winproc.obj: winprog.asm winprog.inc TASM winprog Этот процесс построения требует использования следующего файла определений компоновщика WINPROG.DEF: NAME WINPROG EXETYPE WINDOWS CODE MOVEABLE DISCARDABLE DATA MOVEABLE MULTIPLE DISCARDABLE STACKSIZE 5120 ; минимум для прикладных ; программ Windows ;----------------------------------------------------------- ; Определить импортируемые функции. (Это не обязательно, ес- ; ли вы выполняете компоновку с библиотекой импорта типа ; IMPORT.LIB или LIBW.LIB.) ;----------------------------------------------------------- IMPORTS DLLPROG.SetHello
                       Назад | Содержание | Вперед