Приложение 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
Назад | Содержание | Вперед