Turbo Assembler 3.0. Руководство пользователя

         

Symbol is not a segment or already part of a group


(Имя идентификатора не является именем сегмента либо уже оп- ределено в группе)

Либо имя идентификатора уже определено в группе, либо не яв- ляется именем сегмента. Например:

DATA SEGMENT DATA ENDS DGROUP GROUP DATA DGROUP2 GROUP DATA ; ошибка: DATA уже определено в DGROUP



Таблица виртуальных методов


Таблица виртуальных методов (ТВМ) представляет собой табли- цу адресов процедур, которые выполняют виртуальные методы. Обычно данная таблица размещается в сегменте данных программы. Любой объект, содержащий виртуальные методы, требует, чтобы где-либо в программе находился экземпляр таблицы виртуальных методов.

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

INCLUDE list.aso DATASEG TBLINST



Текстовые макрокоманды


Текстовая макрокоманда - это идентификатор, представляющий строку текстовых символов. Когда Турбо Ассемблер обнаруживает идентификатор в выражениях (и в других ситуациях), он подставляет вместо него текстовые символы. Например, если DoneMsg - это текс- товая макрокоманда, имеющая значение "Returning to DOS", то сле- дующий оператор:

GoodBy DB DoneMsg

дает в результате:

GoodBy DB 'Returning to DOS'



Текстовые справочные файлы




В состав Турбо Ассемблера входят несколько справочных фай- лов: FILELIST.DOC. README, HELPME!.TSM, MANUAL.TSM, H2ASH.TSM и TCREF.TSM. Первые два файла содержатся на установочной дискете "Installation Disk" и копируются в основной каталог языка. Другие файлы находятся в подкаталоге DOC.



Тело макрокоманды, состоящей из нескольких строк


Независимо от содержимого тела макрокоманды, средство обра- ботки макрокоманд Турбо Ассемблера интерпретирует макрокоманду, состоящую из нескольких строк, как просто несколько строк текста. Турбо Ассемблер позволяет вам заменить идентификаторы в теле мак- рокоманды текстом, заданным при вызове макрокоманды. Это средство называется подстановкой аргументов. Идентификаторы в теле макро- команды, которые должны быть заменены, называются формальными (фиктивными) аргументами. Предположим, например, что идентифика- тор foo - это формальный аргумент в следующем теле макрокоманды:

PUSH foo MOV foo,1

Если при вызове данной макрокоманды вы присваиваете foo текстовую строку AX, то фактическим включаемым в модуль текст бу- дет:

PUSH foo MOV AX,1

Правила, которые Турбо Ассемблер использует для распознава- ния формальных аргументов, достаточно сложны. Рассмотрим, напри- мер, следующие строки тела макрокоманды, где формальный аргумент foo не распознается:

symfoo: DB 'It is foo time'

В общем случае Турбо Ассемблер не будет распознавать фор- мальный аргумент (без специального указания) в следующих ситуаци- ях:

- когда он является частью другого идентификатора;

- когда он находится внутри кавычек (' или ");

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



Терминология


Для различных единиц объектно-ориентированного программиро- вания в C++ и Паскале используются различные термины. В этом смысле Турбо Ассемблер более близок к Паскалю, хотя не все терми- ны здесь совпадают. Различия между языками описываются в следую- щей таблице:

Терминология объектно-ориентированного программирования Таблица 4.1 ------------------------T----------------------T----------------¬ ¦Турбо Ассемблер ¦ Borland C++ ¦ Турбо Паскаль ¦ +-----------------------+----------------------+----------------+ ¦метод ¦ функция-элемент ¦ метод ¦ ¦ ¦ ¦ ¦ ¦процедура метода ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦объект ¦ класс ¦ объект ¦ ¦ ¦ ¦ ¦ ¦базовый объект ¦ базовый класс ¦ базовый объект ¦ ¦ ¦ ¦ ¦ ¦порождающий объект ¦ порождающий класс ¦ порождающий ¦ ¦ ¦ ¦ объект ¦ ¦ ¦ ¦ ¦ ¦порожденный объект ¦ порожденный класс ¦ порожденный ¦ ¦ ¦ ¦ объект ¦ ¦ ¦ ¦ ¦ ¦поле порожденного ¦ элемент данных ¦ поле ¦ ¦ объекта ¦ ¦ ¦ L-----------------------+----------------------+-----------------

Примечание: Эти термины подробнее поясняются в данной главе ниже.



Text macro expansion exceeds maximum line length


(Расширение текстовой макрокоманды превышает максимально до- пустимую длину)

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



Типы идентификаторов


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

Типы идентификаторов Таблица 5.4 ----------------------------T------------------------------------¬ ¦ Тип идентификатора ¦ Описание ¦ +---------------------------+------------------------------------+ ¦ адрес ¦ Адрес. Подтипами данных являются ¦ ¦ ¦ типы UNKNOWN, BYTE, WORD, DWORD, ¦ ¦ ¦ PWORD, QWORD, TBYTE и адрес струк- ¦ ¦ ¦ туры или таблицы с указанным име- ¦ ¦ ¦ нем. Подтипами кода являются ¦ ¦ ¦ SHORT, NEAR, FAR. ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ текстовая макрокоманда ¦ Текстовая строка. ¦ ¦ ¦ ¦ ¦ псевдоним ¦ Эквивалентный идентификатор. ¦ ¦ ¦ ¦ ¦ числовое выражение ¦ Значение числового выражения. ¦ ¦ ¦ ¦ ¦ макрокоманда из ¦ Несколько текстовых строк с пус- ¦ ¦ нескольких строк ¦ тыми аргументами. ¦ ¦ ¦ ¦ ¦ структура/объединение ¦ Тип данных структуры или объеди- ¦ ¦ ¦ нения. ¦ ¦ ¦ ¦ ¦ таблица ¦ Табличный тип данных. ¦ ¦ ¦ ¦ ¦ элемент структуры/ ¦ Элемент структуры или таблицы. ¦ ¦ таблицы ¦ ¦ ¦ ¦ ¦ ¦ запись ¦ Данные типа записи. ¦ ¦ ¦ ¦ ¦ поле записи ¦ Поле записи. ¦ ¦ ¦ ¦ ¦ перечисление ¦ Перечислимый тип данных. ¦ ¦ ¦ ¦ ¦ сегмент ¦ Сегмент. ¦ ¦ ¦ ¦ ¦ группа ¦ Группа. ¦ ¦ ¦ ¦ ¦ тип ¦ Названный тип. ¦ L---------------------------+-------------------------------------



Типы меток


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

. . . SmallCount DB 0 . . . mov WORD PTR [SmallCount],0ffffh . . .

Поэтому важно, чтобы в операторе Ассемблера EXTRN, в котором описываются переменные С++, задавался правильный размер этих пе- ременных, так как при генерации размера доступа к переменной С++ Турбо Ассемблер основывается именно на этих описаниях.

Если в программе на языке С++ содержится оператор:

char c

то код Ассемблера:

. . . EXTRN c:WORD . . . inc [c] . . .

может привести к весьма неприятным ошибкам, поскольку после того, как в коде на языке С++ переменная c увеличится очередные 256 раз, ее значение будет сброшено, а так как она описана, как пере- менная размером в слово, то байт по адресу OFFSET c + 1 будет увеличиваться некорректно, что приведет к непредсказуемым резуль- татам.

Между типами данных С++ а Ассемблера существует следующее соотношение:

--------------------------------T-------------------------------¬ ¦ Тип данных С++ ¦ Тип данных Ассемблера¦ +-------------------------------+-------------------------------+ ¦ unsigned char ¦ byte ¦ ¦ char ¦ byte ¦ ¦ enum ¦ word ¦ ¦ unsigned short ¦ word ¦ ¦ short ¦ word ¦ ¦ unsigned int ¦ word ¦ ¦ int ¦ word ¦ ¦ unsigned long ¦ dword ¦ ¦ long ¦ dword ¦ ¦ float ¦ dword ¦ ¦ double ¦ qword ¦ ¦ long double ¦ tbyte ¦ ¦ near* ¦ word ¦ ¦ far* ¦ dword ¦ L-------------------------------+--------------------------------



Турбо Паскаль использует те же


Турбо Паскаль использует те же соглашения о передаче пера- метров для 8087, что и семейство компиляторов Borland C++. Пара- метры передаются через главный стек центрального процессора, вместе с остальными параметрами.


Точность в выражениях


Турбо Ассемблер в режиме Ideal всегда использует 32-разряд- ную арифметику. В режиме MASM Турбо Ассемблер использует 16- или 32-разрядную арифметику, в зависимости от выбора процессора 80386. Таким образом, некоторые выражения, в зависимости от того, какой процессор выбирается, могут давать разные результаты. Нап- ример, при вычислении:

(1000h * 1000h) / 1000h

получается 1000h при выборе процессора 80386 или 0 при выборе процессоров 8086, 80186 или 80286.



Too few operands to instruction


(В команде не хватает операндов)

В команде должно быть указано большее число операндов. Нап- ример:

ADD ax ; отсутствует второй операнд



Too many errors found


(Обнаружено слишком много ошибок)

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

Турбо Ассемблер прекращает ассемблирование файла, когда об- щее число ошибок и предупреждающих сообщений достигает 100.



Too many errors or warnings


(Слишком много ошибок или предупреждений)

Сообщения об ошибках больше выдаваться не будут. Максималь- ное число сообщений об ошибках, которое выдается Турбо Ассембле- ром, равно 100. Это максимально допустимое число ошибок превыше- но. Ассемблирование программы тем не менее будет продолжено, однако далее будут печататься только предупреждающие сообщения.



Too many initial values


(Слишком много начальных значений)

При инициализации структуры или объединения указано слишком много значений. Например:

XYZ STRUC A1 DB ? A2 DB ? XYZ ENDS ANXYZ XYZ <1,2,3> ; ошибка: в XYZ определены ; только два поля

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



Too many register multipliers in expression


(В выражении содержится слишком много множителей для регист- ров)

Для процессора 80386 допускается коэффициент индексных опе- рандов. Однако коэффициент можно указывать не более, чем у одного регистра. Например:

mov EAX,[2*EBX+4*EDX] ; слишком много ; коэффициентов



Too many registers in expression


(В выражении указано слишком много регистров)

В выражении указано более одного индексного и одного базис- ного регистра. Например:

mov ax,[BP+SI+DI] ; нельзя одновременно указывать SI и DI



Too many USES registers


(Слишком много регистров в директиве USES)

В директиве USES для текущей процедуры указано более 8 ре- гистров.



Trailling null value assumed


(Предполагается конечное пустое значение)

Директива определения данных (DB, DW и т.д.) оканчивается запятой. TASM интерпретирует ее как пустое значение. Например:

db 'привет',13,10 ; то же, что и db'привет',13,10?



Требования к программному и аппаратному обеспечению


Турбо Ассемблер работает на компьютерах семейства IBM PC, включая модели XT, AT и PS/2, а также на полностью совместимых с ними компьютерах. Для работы Турбо Ассемблера требуется операци- онная система MS-DOS (версии 2.0 или более поздняя) и не менее 256К оперативной памяти.

Турбо Ассемблер генерирует инструкции процессоров 8086, 80186, 80286, 80386 и i486, а также инструкции с плавающей точкой для арифметических сопроцессоров 8087, 80287 и 80387. (Подробнее об инструкциях процессором семейства 80х86/80х87 рассказывается в книгах фирмы Intel.)



Турбо Ассемблер 3.0/tasm/#1-2. Руководство пользователя.


Введение

Требования к программному и аппаратному обеспечению

Поддержка DPMI

О данной документации

Руководство пользователя

Соглашения по обозначениям

Как обратиться за помощью к фирме Borland

Ресурсы вашего пакета

Возможности фирмы Borland

ЧАСТЬ 1. ИСПОЛЬЗОВАНИЕ ТУРБО АССЕМБЛЕРА

Глава 1. Начало работы на Турбо Ассемблере

Установка Турбо Ассемблера в системе

Текстовые справочные файлы

Файл README

Файл HELPME!.TSM

Файл H2ASH.TSM

Файл TCREF.TSM

Оперативный справочник

Ваша первая программа на Турбо Ассемблере

Ассемблирование вашей первой программы

Компоновка программы

Запуск вашей первой программы

Что происходит?

Модификация вашей первой программы на Турбо Ассемблере

Вывод информации на устройство печати

Ваша вторая программа на Турбо Ассемблере

Запуск программы REVERSE.ASM

Литература по языку Ассемблера

Глава 2. Использование директив и параметров

Запуск Турбо Ассемблера из DOS

Параметры командной строки

Параметр /A

Параметр /B

Параметр /C

Параметр /D

Параметр /E

Параметр /H или /?

Параметр /I

Параметр /J

Параметр /KH

Параметр /L

Параметр /LA

Параметр /M

Параметр /ML

Параметр /MU

Параметр /MV#

Параметр /MX

Параметр /N

Параметр /O

Параметр /OP

Параметр /P

Параметр /Q

Параметр /R

Параметр /S

Параметр /T

Параметр /V

Параметр /W

Параметр /X

Параметр /Z

Параметр /ZD

Параметр /ZI

Параметр /ZN

Косвенные командные файлы

Файлы конфигурации

Глава 3. Общие принципы программирования

Режим Ideal Турбо Ассемблера

Для чего используется режим Ideal?

Переключение в режим Ideal и выход из него

Отличия режима Ideal и режима MASM

Выражения и операнды

Операции

Подавление корректировок

Операнд инструкции BOUND

Сегменты и группы

Доступ к данным в сегменте, принадлежащем группе

Комментарии в программах

Комментарии в конце строки

Директива COMMENT

Продолжение строки

Использование включаемых файлов

Предопределенные идентификаторы

Присваивание идентификаторам значений

Общая структура модуля

Директива VERSION


Директива NAME

Директива END

Вывод сообщения в процессе ассемблирования

Вывод предупреждающих сообщений

Вывод нескольких сообщений об ошибках

Глава 4. Объектно-ориентированное программирование

Терминология

Для чего в Турбо Ассемблере используются объекты?

Что такое объект?

Пример объекта

Описание объектов

Описание процедуры методa

Таблица виртуальных методов

Инициализация таблицы виртуальных методов

Вызов метода объекта

Вызов статического метода

Вызов виртуального метода

Вызов виртуальных методов "предков"

Кое-что еще о вызове методов

Создание экземпляра объекта

Программирование с объектами

Пример из области программирования

Глава 5. Использование выражений и значений идентификаторов

Константы

Числовые константы

Изменение используемого по умолчанию основания

Строковые константы

Идентификаторы

Имена идентификаторов

Типы идентификаторов

Адресные подтипы данных

Описание сложного адресного подтипа

Выражения

Точность в выражениях

Константы в выражениях

Идентификаторы в выражениях

Регистры

Стандартные значения идентификаторов

Значения простых идентификаторов

Унарная операция LENGTH

Унарная операция WIDTH

Унарная операция MASK

Общие арифметические операции

Простые арифметические операции

Логические арифметические операции

Поразрядные операции сдвига

Операции сравнения

Задание адресного подтипа выражения

Получение типа выражения

Переопределение сегментной части адресного выражения

Получение сегмента и смещения адресного выражения

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

Определение характеристик выражения

Ссылки на структуры, объединения и смещения элементов в таблице

Описание содержимого адреса

Подразумеваемое сложение

Получение значения старшего или младшего байта выражения

Задание 16- или 32-разрядных выражений



Глава 6. Директивы выбора процессора и идентификаторы процессора



Директивы процессоров iAPx86

Предопределенные идентификаторы

Идентификатор @Cpu

Идентификатор @WordSize



Директивы сопроцессора 8087

Директивы эмуляции сопроцессора

Глава 7. Использование моделей памяти программы и сегментации

Директива MODEL

Идентификаторы, генерируемые директивой MODEL

Идентификатор @Model

Идентификатор @32Bit

Идентификатор @CodeSize

Идентификатор @DataSize

Идентификатор @Interface

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

Идентификаторы, создаваемые упрощенными директивами сегментации

Директива STARTUPCODE

Идентификатор @Startup

Директива EXITCODE

Определение общих сегментов и групп

Директива SEGMENT

Атрибут комбинирования сегментов

Атрибут класса сегмента

Атрибут выравнивания сегмента

Атрибут размера сегмента

Атрибут доступа к сегменту

Директива ENDS

Директива GROUP

Директива ASSUME

Переопределение сегмента

Изменение упорядочивания сегментов в модуле

Директива .ALPHA

Директива .SEQ

Директива DOSSEG: упорядочивание сегментов в порядке DOS

Изменение размера стека

Глава 8. Определение типов данных

Определение перечислимых типов данных

Определение записей с битовыми полями

Определение структур и объединений

Открытие определения структуры или объединения

Задание элементов структуры и объединения

Определение меток элементов структур с помощью директивы LABEL

Выравнивание элементов структуры

Закрытие определения структуры или объединения

Вложенные структуры и объединения

Включение одной именованной структуры в другую

Использование имен структур в выражениях

Определение таблиц

Переопределение элементов таблицы

Определение именованного типа

Определение объекта

Директива TBLPTR

Идентификаторы, определяемые расширенной директивой STRUC

Глава 9. Задание и использование счетчика адреса

Идентификатор счетчика адреса $

Директивы счетчика адреса $

Директива ORG

Директивы EVEN и EVENDATA

Директива ALIGN

Определение меток

Операция :

Директива LABEL

Директива ::

Глава 10. Описание процедур

Синтаксис определения процедур

Описание процедур NEAR или FAR

Описание языка процедуры

Задание модификатора языка

Определения аргументов и локальных переменных



Синтаксис директив ARG и LOCAL

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

Сохранение регистров

Вложенные процедуры и правила области действия

Описание процедур методов для объектов

Глава 11. Управление областью действия идентификаторов

Переопределяемые идентификаторы

Область действия в границах блока

Директивы LOCALS и NOLOCALS

Область действия в границах блока в MASM

Локальные метки в стиле MASM

Глава 12. Определение данных

Простые директивы определения данных

Создание экземпляра структуры или объединения

Инициализация экземпляра структуры или объединения

Создание экземпляра записи

Инициализация экземпляров записи

Создание экземпляра данных перечислимого типа

Инициализация экземпляра перечислимого типа данных

Создание экземпляра таблицы

Инициализация экземпляров таблицы

Создание и инициализация экземпляра именованного типа данных

Создание экземпляра объекта

Создание экземпляра таблицы виртуальных методов объекта

Глава 13. Расширенные инструкции

Эффективная генерация кода: директивы SMART и NOSMART

Расширенные инструкции перехода

Дополнительные инструкции цикла процессора 80386

Дополнительные инструкции ENTER и LEAVE

Дополнительные инструкции возврата

Расширенные инструкции PUSH и POP

Инструкции PUSH и POP с несколькими операндами

Использование в инструкциях PUSH и POP указателей

Занесение в стек константа (процессор 8086)

Расширенные инструкции сдвига

Принудительное переопределение сегментов: инструкции SEGxx

Дополнительные инструкции работы с флагами

Дополнительные инструкции работы с битами полей

Инструкция GETFIELD

Дополнительная быстрая инструкции непосредственного умножения.

Расширение необходимых инструкций для процессора 80386

Вызов процедур с кадрами стека

Вызываемые процедуры, содержащие RETURNS

Вызов процедур методов для объектов: CALL...METHOD

Остаточная рекурсия для методов объектов: инструкция JMP...METHOD

Дополнительные инструкции для объектного программирования

Глава 14. Использование макрокоманд



Текстовые макрокоманды

Определение текстовых макрокоманд с помощью директивы EQU

Директивы макрокоманд работы с текстовыми строками

Директива CATSTR

Директива SUBSTR

Директива INSTR

Директива SIZESTR

Примеры макрокоманд работы с текстом

Макрокоманды, состоящие из нескольких строк

Тело макрокоманды, состоящей из нескольких строк

Использование в макрокомандах символа &

Включение комментариев в тело макрокоманды

Локальные формальные аргументы

Директива EXITM

Директива GOTO и макроидентификаторы перехода

Общие макрокоманды, состоящие из нескольких строк

Вызов общей макрокоманды, состоящей из нескольких строк

Литеральные строки в угловых скобках

Символ !

Символ вычисления выражения %

Переопределение общей макрокоманды, состоящей из нескольких строк

Удаление общей макрокоманды: директива PURGE

Определение вложенных и рекурсивных макрокоманд

Счетчик повторения макрокоманды

Директива WHILE

Макрокоманды повторения строк

Непосредственная макродиректива %

Включение расширения макрокоманды в файл листинга

Глава 15. Использование условных директив

Синтаксис условных директив

Директива условного ассемблирования IFxxx

Директивы условного ассемблирования ELSEIFxxx

Директивы генерации сообщений об ошибке ERRxx

Описания конкретных директив

Безусловные директивы генерации сообщений об ошибке

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

Условные директивы с идентификатором

Условные директивы с текстовыми строками

Условия выполнения прохода Ассемблером

Включение условных директив в файл листинга

Глава 16. Интерфейс с компоновщиком

Описание внешних идентификаторов

Соглашения для конкретного языка

Описание общедоступных идентификаторов

Описание идентификаторов библиотеки

Определение внешних идентификаторов

Описание глобальных идентификаторов

Определение общих переменных

Включение библиотеки

Глава 17. Генерация листинга

Формат листинга

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

Директивы листинга включаемых файлов

Директивы вывода блоков условного ассемблирования



Директивы вывода в файл листинга макрокоманд

Директивы вывода листинга перекрестных ссылок

Параметры изменения формата листинга

Глава 18. Интерфейс Турбо Ассемблера и Borland C++

Вызов из Borland C++ функций Турбо Ассемблера

Основные моменты в интерфейсе Турбо Ассемблера и Borland C++

Компоновка ассемблерных модулей с С++

Использование Extern "C" для упрощения компоновки

Модели памяти и сегменты

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

Старые директивы определения сегментов и Borland C++

Значения по умолчанию: когда необходимо загружать сегменты?

Общедоступные и внешние идентификаторы

Подчеркивания и язык Си

Различимость строчных и прописные символов в идентификаторах

Типы меток

Внешние дальние идентификаторы

Командная строка компоновщика

Взаимодействие между Турбо Ассемблером и Borland C++

Передача параметров

Сохранение регистров

Возврат значений

Вызов функции Турбо Ассемблера из Borland C++

Написание на языке Ассемблера функций-элементов С++

Соглашения по вызовам, использующиеся в Паскале

Вызов Borland C++ из Турбо Ассемблера

Компоновка с кодом инициализации С++

Задание сегмента

Выполнение вызова

Вызов из Турбо Ассемблера функции Borland C++

Глава 19. Интерфейс Турбо Ассемблера с Турбо Паскалем

Совместное с Турбо Паскалем использование данных

Директива компилятора $L и внешние подпрограммы

Директива PUBLIC

Директива EXTRN

Ограничения при использовании объектов типа EXTRN

Использование корректировок сегментов

Устранение неиспользуемого кода

Соглашения Турбо Паскаля по передаче параметров

Параметры-значения

Скалярные типы

Вещественные значения

Типы Single, Double, Extended и Comp и типы сопроцессора 8087

Указатели

Строки

Записи и массивы

Множества

Параметры-переменные

Обеспечение стека

Доступ к параметрам

Использование для адресации к стеку регистра BP

Директива ARG

Турбо Паскаль и директива .MODEL

Использование другого базового или индексного регистра

Результаты функции в Турбо Паскале



Выделение пространства для локальных данных

Выделение статической памяти

Выделение временной памяти

Примеры подпрограмм на Ассемблере для Турбо Паскаля

Подпрограмма шестнадцатиричного преобразования общего назначения

Пример обмена содержимого двух переменных

Пример анализа операционной среды DOS

Часть 2. ПРИЛОЖЕНИЯ 1

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

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

Программы DOS

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

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

Программы Windows

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

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

Приложение B. Обзор синтаксических правил Турбо Ассемблера

Лексическая грамматика

Грамматика выражений в режиме MASM

Грамматика выражений в режиме Ideal

Старшинство ключевых слов

Старшинство операций в режиме Ideal

Старшинство операций в режиме MASM

Ключевые слова и предопределенные идентификаторы

Ключевые слова директив

Приложение C. Вопросы совместимости

Одно- и двухпроходные режимы ассемблирования

Переменные операционной среды

Формат фирмы Microsoft для двоичных чисел с плавающей точкой

Приложение D. Утилиты Турбо Ассемблера

Утилита-преобразователь H2ASH

Приложение E. Сообщения об ошибках

Информационные сообщения

Предупреждающие сообщения и сообщения об ошибках

32-bit segment not allowed without .386

Argument needs type override

Argument to operation or instruction has illegal size

Arithmetic overflow

ASSUME must be segment register

Bad keyword in SEGMENT statement

Can't add relative quantities

Can't address with currently ASSUMEd segment registers

Can't convert to pointer

Can't emulate 8087 instruction

Can't make variable public

Can't override ES segment

Can't subtract dissimilar relative quantities

Can't use macro name in expression

Can't use this outside macro

Code or data emission to undeclared segment

Constant assumed to mean Immediate const

Constant too large

CS not correctly assumed

CS override in protected mode



CS unreachable from current segment

Declaration needs name

Directive ignored in Turbo Pascal model

Directive not allowed inside structure definition

Duplicate dummy arguments:_

ELSE or ENDIF without IF

Expecting METHOD keyword

Expecting offset quantity

Expecting offset or pointer quantity

Expecting pointer type

Expecting record field name

Expecting register ID

Expecting scalar type

Expecting segment or group quantity

Extra characters on line

Forward reference needs override

Global type doesn't match symbol type

ID not member of structure

Illegal forward reference

Illegal immediate

Illegal indexing mode

Illegal instruction

Illegal instruction for currently selected processor(s)

Illegal local argument

Illegal local symbol prefix

Illegal mаcro argument

Illegal memory reference

Illegal number

Illegal origin address

Illegal override in structure

Illegal override register

Illegal radix

Illegal register for instruction

Illegal register multiplier

Illegal segment address

Illegal use of constant

Illegal use of register

Illegal use of segment register

Illegal USES register

Illegal version ID

Illegal warning ID

Instruction can be compacted with override

Invalid model type

Invalid operand(s) to instruction

Labels can't start with numeric characters

Line too long - truncated

Location counter overflow

Method call requires object name

Missing argument list

Missing argument or <

Missing argument size variable

Missing COMM ID

Missing dummy argument

Missing end quote

Missing macro ID

Missing module name

Missing or illegal language ID

Missing or illegal type specifier

Missing table member ID

Missing term in list

Missing text macro

Model must be specified first

Module is pass-dependant - compatibility pass was done

Name must come first

Near jump or call to different CS

Need address or register

Need angle brackets for structure fill

Need colon

Need expression

Need file name after INCLUDE

Need left parenthesis

Need method name



Need pointer expression

Need quoted string

Need register in expression

Need right angle bracket

Need right curly bracket

Need right parenthesis

Need right square bracket

Need stack argument

Need structure member name

Not expecting group or segment quantity

One non-null field allowed per union expansion

Only one startup sequence allowed

Open conditional

Open procedure

Open segment

Open structure definition

Operand types do not match

Operation illegal for static table member

Pass-dependant construction encountered

Pointer expression needs brackets

Positive count expecting

Record field too large

Record member not found

Recursive definition not allowed for EQU

Register must be AL or AX

Register must be DX

Relative jump out of range by __ bytes

Relative quantity illegal

Reserved word used as symbol

Rotate count must be constant or CL

Rotate count out of range

Segment alignment not strict enough

Segment attributes illegally redefined

Segment name is superfluous

String too long

Symbol already defined:__

Symbol already different kind

Symbol has no width or mask

Symbol is not a segment or already part of a group

Text macro expansion exceeds maximum line length

Too few operands to instruction

Too many errors or warnings

Too many initial values

Too many register multipliers in expression

Too many registers in expression

Too many USES registers

Trailling null value assumed

Undefined symbol

Unexpected end of file (no END directive)

Unknown character

Unmatched ENDP:_

Unmatched ENDS:_

User-generated error

Value out of range

Сообщения о фатальных ошибках

Bad switch

Can't find @file __

Сan't locate file __

Error writing to listing file

Error writing to object file

File not found

File was changed or deleted while assembly in progress

Insufficient memory to process command line

Internal error

Invalid command line

Invalid number after _

Out of hash space

Out of memory

Out of string space

Too many errors found

Unexpected end of file (no END directive)

Дополнение для Borland C++ 3.1. Новые средства Турбо ассемблера версии 3.1

Вперед >>>


Турбо Паскаль и директива .MODEL


Директива .MODEL с параметром TPASCAL задает упрощенную сег- ментацию, модель памяти и языковую поддержку. Обычно используется большая модель памяти (large) Ранее мы уже видели, что нужно сде- лать в программах Ассемблера, чтобы можно было использовать про- цедуры и функции Паскаля. Преобразуем пример, используя в нем ди- рективы .MODEL и PROC:

.MODEL large, PASCAL .CODE MyProc PROC FAR i:BYTE,j:BYTE result:DWORD PUBLIC MyProc mov ax,i . . . ret

Заметим, что теперь не нужно задавать параметры в обратном порядке. Не требуется также масса других операторов. Использова- ние в директиве .MODEL ключевого слова PASCAL задает использова- ние соглашений Паскаля, определяет имена сегментов, выполняет инструкции PUSH BP и MOV BP,SP и задает также возврат с помощью инструкций POP BP и RETn (где n - число байт параметров).



Удаление общей макрокоманды: директива PURGE


Для удаления макрокоманд вы можете использовать директиву PURGE. Директива PURGE имеет следующий синтаксис:

PURGE имя_макрокоманды, [имя_макрокоманды].

Директива PURGE удаляет определение макрокоманды, состоящей из нескольких строк, с именем "имя_макрокоманды" После использо- вания директивы PURGE Турбо Ассемблер больше не интерпретирует идентификатор PURGE как макрокоманду, например:

ADD MACRO a1,a2 SUB a1,a2 ENDM ADD ax,bx ; этот вызов даст SUB ax,bx PURGE ADD ADD ax,bx ; теперь это не макрокоманда, поэтому ; вы получите ADD ax,bx

Вы можете сразу удалить этой директивой несколько макроко- манд, разделив их имена запятыми. Отметим однако, что идентифика- тор удаленной макрокоманды можно переопределить только другой макрокомандой.



Указатели


Значения параметров для всех типов указателей заносятся не- посредственно в стек, как указатели дальнего типа: сначала слово, содержащее сегмент, затем другое слово, содержащее смещение. Сег- мент занимает старший адрес, в соответствии с соглашениями фирмы Intel. Для извлечения параметра-указателя в программе Турбо Ас- семблера можно использовать инструкции LDS или LES.



Унарная операция LENGTH


Унарная операция LENGTH возвращает информацию о счетчике или числе величин, представляющих идентификатор. Возвращаемое факти- ческое значение зависит от типа идентификатора, что показано в приведенной ниже таблице:

Значения, возвращаемые операцией LENGTH Таблица 5.11 --------------------------------T-------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------------+-------------------------------+ ¦ LENGTH имя_адреса ¦ Возвращает счетчик элементов, ¦ ¦ ¦ выделяемых при определении ¦ ¦ ¦ имени адреса. ¦ ¦ ¦ ¦ ¦ LENGTH имя_элемента_структуры/¦ Возвращает счетчик элементов, ¦ ¦ объединения ¦ выделенных при определении ¦ ¦ ¦ элемента (только режим MASM). ¦ L-------------------------------+--------------------------------

При применении ее ко всем другим типам идентификаторов опе- рация LENGTH возвращает значение 1. Приведем некоторые примеры использования операции LENGTH:

MSG DB "Hello" array DW 10 DUP (4 DUP (1),0) numbrs DD 1,2,3,4 lmsg = LENGTHG msg ; =1, нет операции DUP larray = LENGTH nsg ; =10, счетчик повторения DUP lnumbrs = LENGTH numbrs ; =1, нет операции DUP

Унарная операция SIZE

Унарная операция SIZE возвращает информацию о размере выде- ленного элемента данных. Возвращаемое значение зависит от типа заданного идентификатора. Список доступных для операции SIZE зна- чений приведен в следующей таблице: Значения, возвращаемые операцией SZIE Таблица 5.12 ------------------------------T---------------------------------¬ ¦ Выражение ¦ Значение ¦ +-----------------------------+---------------------------------+ ¦ SIZE имя_адреса ¦ В режиме Ideal возвращается ¦ ¦ ¦ фактическое число байт, выде- ¦ ¦ ¦ ленных для переменных данных. ¦ ¦ ¦ В режиме MASM возвращается ¦ ¦ ¦ размер подтипа имя_адреса ¦ ¦ ¦ (UNKNOWN=0, BYTE=1, WORD=2, ¦ ¦ ¦ DWORD=4, PWORD=FWORD=6, QWORD ¦ ¦ ¦ =8, TBYTE=10, SHORT=NEAR= ¦ ¦ ¦ 0ffffh, FAR=0fffeh, адрес ¦ ¦ ¦ структуры = размеру структу- ¦ ¦ ¦ ры), умноженный на значение ¦ ¦ ¦ LENGTH имя_адреса. ¦ ¦ SIZE имя_структуры/ ¦ Возвращает число байт, требу- ¦ ¦ объединения ¦ емых для представления струк- ¦ ¦ ¦ туры или объединения. ¦ ¦ SIZE имя_таблицы ¦ Возвращает число байт, необ- ¦ ¦ ¦ ходимых для представления ¦ ¦ ¦ таблицы. ¦ ¦ SIZE имя_элемента_таблицы/ ¦ Возвращает величину TYPE имя ¦ ¦ структуры ¦ _элемента_таблицы/структуры* ¦ ¦ ¦ LENGTH имя_элемента_таблицы/ ¦ ¦ ¦ объединения (только для ре- ¦ ¦ ¦ жима MASM). ¦ ¦ SIZE имя_записи ¦ Возвращает число байт, не- ¦ ¦ ¦ обходимых для представления ¦ ¦ ¦ общего числа бит, зарезерви- ¦ ¦ ¦ рованных в определении запи- ¦ ¦ ¦ си: 1, 2 или 4. ¦ ¦ SIZE имя_перечисления ¦ Возвращает число байт, необ- ¦ ¦ ¦ ходимых для представления ¦ ¦ ¦ максимального значения, при- ¦ ¦ ¦ сутствующего в перечислении: ¦ ¦ ¦ 1, 2 или 4. ¦ ¦ SIZE имя_сегмента ¦ Возвращает размер сегмента ¦ ¦ ¦ в байтах. ¦ ¦ SIZE имя_типа ¦ Возвращает число байт, необ- ¦ ¦ ¦ ходимых для представления ¦ ¦ ¦ названного типа, при этом ¦ ¦ ¦ ближние и дальние метки воз- ¦ ¦ ¦ вращают значение 0ffffh, а ¦ ¦ ¦ дальние - 0fffeh. ¦ L-----------------------------+----------------------------------

При применении ко всем другим типам идентификаторов операция SIZE возвращает значение 0.



Унарная операция MASK


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

Значения, возвращаемые MASK Таблица 5.14 --------------------------T-------------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------+-------------------------------------+ ¦ MASK имя_записи ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ резервированные для представления ¦ ¦ ¦ битовых полей в определении записи, ¦ ¦ ¦ равны 1, а остальные равны 0. ¦ ¦ ¦ ¦ ¦ MASK имя_поля_записи ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ резервированные для поля в определе-¦ ¦ ¦ нии записи, равны 1, а остальные ¦ ¦ ¦ равны 0. ¦ ¦ ¦ ¦ ¦ MASK имя_перечисления ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ резервированные для представления ¦ ¦ ¦ максимального значения в определе- ¦ ¦ ¦ нии перечисления, равны 1, а ос- ¦ ¦ ¦ тальные равны 0. ¦ L-------------------------+--------------------------------------



Унарная операция WIDTH


Унарная операция WIDTH возвращает размер в битах поля запи- си. Это значение зависит от типа идентификатора. Эти типы иденти- фикаторов показаны в приведенной ниже таблице. Для всех других типов операцию WIDTH использовать не допускается.

Значения WIDTH Таблица 5.13 --------------------------T-------------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------+-------------------------------------+ ¦ WIDTH имя_записи ¦ Возвращает общее число бит, заре-¦ ¦ ¦ зервированных в определении записи.¦ ¦ ¦ ¦ ¦ WIDTH имя_поля_записи ¦ Возвращает число бит, зарезервиро-¦ ¦ ¦ ванных для поля в определении запи-¦ ¦ ¦ си. ¦ ¦ ¦ ¦ ¦ WIDTH имя_перечисления ¦ Возвращает число бит, необходимых ¦ ¦ ¦ для представления максимального ¦ ¦ ¦ значения в определении enum. ¦ L-------------------------+--------------------------------------



Undefined symbol


(Идентификатор не определен)

Оператор содержит идентификатор, который не был ранее опре- делен в исходном файле.



Unexpected end of file (no END directive)


(Неожиданный конец файла (нет директивы END))

В исходном файле отсутствует директива END. Директива END обязательно должна быть указана в конце исходного файла.



Unknown character


(Неизвестный символ)

Текущая строка исходной программы содержит символ, который не принадлежит набору символов, допустимых для построения симво- лических имен и выражений в Турбо Ассемблере. Например:

add ax,!1 ; ошибка: восклицательный знак - ; недопустимый символ



Unmatched ENDP:_


(Непарная директива ENDP:_)

В директиве ENDP указано имя, не совпадающее с именем проце- дуры, которую закрывает данная директива. Например:

ABC PROC XYZ ENDP ; ошибка: вместо XYZ должно быть указано ABC



Unmatched ENDS:_


(Непарная директива ENDS:_)

В директиве ENDS указано имя, не совпадающее с именем сег- мента, который закрывает данная директива, либо не совпадающее с именем структуры или объединения, оканчивающегося этой директи- вой. Например:

ABC STRUC XYZ ENDP ; ошибка: вместо XYZ должно быть указано ABC DATA SEGMENT CODE ENDS ; ошибка: вместо CODE должно быть указано DATA



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


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

Используемые по умолчанию сегменты и типы для модели памяти 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----------------------------------------------------------------


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


Директива .MODEL указывает Турбо Ассемблеру, что сегменты, создаваемые с помощью упрощенных директив определения сегментов, должны быть совместимы с выбранной моделью памяти (TINY - крохот- ной, SMALL - малой, COMPACT - компактной, MEDIUM - средней, LARGEбольшой или HUGE - громадной) и управляет назначаемым по умолчанию типом (FAR или NEAR) процедур, создаваемых по директиве PROC. Модели памяти, определенные с помощью директивы .MODEL, совместимы с моделями Borland C++ с соответствующими именами.

Наконец, упрощенные директивы определения сегментов .DATA, .CODE, .DATA?, .FARDATA, .FARDATA? и .CONST генерируют сегменты, совместимые с Borland C++.

Например, рассмотрим следующий модуль Турбо Ассемблера с именем DOTOTAL.ASM:

.MODEL SMALL ; выбрать малую модель памяти ; (ближний код и данные) .DATA ; инициализация сегмента данных, ; совместимого с Borland C++ EXTRN _Repetitions:WORD ; внешний идентификатор PUBLIC _StartingValue ; доступен для других модулей _StartValue DW 0 .DATA? ; инициализированный сегмент ; данных, совместимый с Borland C++ RunningTotal DW ? .CODE ; сегмент кода, совместимый с ; Borland C++ PUBLIC _DoTotal _DoTotal PROC ; функция (в малой модели памяти ; вызывается с помощью вызова ; ближнего типа) mov cx,[_Repetitions] ; счетчик выполнения mov ax,[_StartValue] mov [RunningTotal],ax ; задать начальное ; значение TotalLoop: inc [RunningTotal] ; RunningTotal++ loop TotalLoop mov ax,[RunningTotal] ; возвратить конечное ; значение (результат) ret _DoTotal ENDP END

Написанная на Ассемблере процедура _DoTotal при использова- нии малой модели памяти может вызываться из Borland C++ с помощью оператора:

DoTotal();

Заметим, что в процедуре DoTotal предполагается, что где-то в другой части программы определена внешняя переменная Repetitions. Аналогично, переменная StartingValue объявлена, как общедоступная, поэтому она доступна в других частях программы. Следующий модуль Borland C++ (который называется SHOWTOT.CPP) об- ращается к данным в DOTOTAL.ASM и обеспечивает для модуля DOTOTAL.ASM внешние данные:


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

Директивы генерации сообщения об ошибке Таблица 15.5 -------------------------T--------------------------------------¬ ¦Директива IFxxx ¦ Ассемблирует "тело_условия_true" если¦ +------------------------+--------------------------------------+ ¦ERRIFDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение true. ¦ ¦ ¦ ¦ ¦.ERRDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение true (только для режима¦ ¦ ¦ MASM). ¦ ¦ ¦ ¦ ¦ERRIFNDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение false. ¦ ¦ ¦ ¦ ¦.ERRNDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение false (только в режиме¦ ¦ ¦ MASM). ¦ L------------------------+---------------------------------------

Например, следующие условия генерации сообщения об ошибке эквивалентны и приводят к генерации ошибки в случае определения foo и bar:

ERRIFDEF foo AND bar ERRIFNDEF NOT ( foo AND bar ) ERRIFBDEF NOT foo OR NOT bar


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


После выбора модели памяти вы можете использовать упрощенные сегментные директивы для того, чтобы начинать отдельные сегменты. Эти упрощенные директивы вы можете использовать только после ди- рективы MODEL, которая задает для модуля модель памяти. В модуле допускается указывать столько директив сегментации, сколько необ- ходимо. Турбо Ассемблер для получения одного сегмента комбинирует все части с одинаковыми именами (как если бы вы ввели все эти фрагменты после одной директивы сегментации). Перечень директив содержится в Таблице 7.4.

--------------------------T-------------------------------------¬ ¦ Директива ¦ Описание ¦ +-------------------------+-------------------------------------+ ¦ CODESEG [имя] ¦ Начинает или продолжает сегмент кода¦ ¦ ¦ модуля. Для моделей с дальним типом¦ ¦ ¦ кода вы можете задать имя, являющее-¦ ¦ ¦ ся фактическим именем сегмента. За-¦ ¦ ¦ метим, что таким образом вы можете¦ ¦ ¦ генерировать для модуля более одного¦ ¦ ¦ сегмента кода. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .CODE [имя] ¦ Эквивалентна директиве CODESEG. До-¦ ¦ DATASEG ¦ пускается только для режима MASM.¦ ¦ ¦ Начинает или продолжает ближний или¦ ¦ ¦ инициализируемый по умолчанию сег-¦ ¦ ¦ мент данных. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .DATA ¦ Эквивалентна директиве DATASEG. До-¦ ¦ CONST ¦ пускается только для режима MASM.¦ ¦ ¦ Начинает или продолжает сегмент¦ ¦ ¦ констант модуля. Постоянные данные¦ ¦ ¦ всегда являются ближними (NEAR) и¦ ¦ ¦ эквивалентны инициализированным дан-¦ ¦ ¦ ным. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .CONST ¦ Эквивалентна директиве CONST. До-¦ ¦ UDATASEG ¦ пускается только для режима MASM.¦ ¦ ¦ Начинает или продолжает ближний или¦ ¦ ¦ не инициализируемый по умолчанию¦ ¦ ¦ сегмент данных. Соблюдайте осторож-¦ ¦ ¦ ность и включайте в этот сегмент¦ ¦ ¦ только неинициализированные данные,¦ ¦ ¦ в противном случае получаемая выпол-¦ ¦ ¦ няемая программа будет иметь больший¦ ¦ ¦ чем нужно размер. Описание распреде-¦ ¦ ¦ ления неинициализированных данных¦ ¦ ¦ можно найти в Главе 12. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .DATA? ¦ Эквивалентна директиве UDATASEG.¦ ¦ ¦ Действует только для режима MASM. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ STACK [размер] ¦ Начинает или продолжает сегмент ¦ ¦ ¦ стека модуля. Необязательный пара-¦ ¦ ¦ метр "размер" определяет объем ре-¦ ¦ ¦ зервируемой для стека памяти (в сло-¦ ¦ ¦ вах). Если вы не задаете размер,¦ ¦ ¦ Турбо Ассемблер резервирует по умол-¦ ¦ ¦ чанию 200h слов (1 килобайт). ¦ ¦ ¦ ¦ ¦ ¦ В режиме MASM все метки, код или¦ ¦ ¦ данные, следующие за оператором¦ ¦ ¦ STACK, не будут рассматриваться как¦ ¦ ¦ часть сегмента стека. Однако в режи-¦ ¦ ¦ ме Ideal резервируется специальная¦ ¦ ¦ область, и сегмент стека остается¦ ¦ ¦ открытым, благодаря чему вы можете¦ ¦ ¦ добавлять метки и другие неинициали-¦ ¦ ¦ зированные данные. ¦ ¦ ¦ ¦ ¦ ¦ Директивы стека обычно требуется ис-¦ ¦ ¦ пользовать, если вы пишете на языке¦ ¦ ¦ Ассемблера автономную программу.¦ ¦ ¦ Большинство языков высокого уровня¦ ¦ ¦ сами создают для вас стек. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .STACK [размер] ¦ Эквивалентна директиве STACK. Дей-¦ ¦ ¦ ствует в режиме MASM. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ FARDATE [имя] ¦ Начинает или продолжает дальний не-¦ ¦ ¦ инициализированный сегмент данных¦ ¦ ¦ (FAR) с заданным именем. Если вы не¦ ¦ ¦ задаете имя, Турбо Ассемблер исполь-¦ ¦ ¦ зует сегментное имя FAR_DATA. В мо-¦ ¦ ¦ дуле может содержаться более одного¦ ¦ ¦ неинициализированного сегмента дан-¦ ¦ ¦ ных типа FAR. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .FARDATA [имя] ¦ Эквивалентна FARDATA. Действует в¦ ¦ ¦ режиме MASM. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ UFARDATA ¦ Начинает или продолжает дальний не-¦ ¦ ¦ инициализированный сегмент данных с¦ ¦ ¦ заданным именем. Если вы не задаете¦ ¦ ¦ имя, то Турбо Ассемблер использует¦ ¦ ¦ имя сегмента FAR_BSS. В модуле у вас¦ ¦ ¦ может быть несколько неинициализиро-¦ ¦ ¦ ванных сегментов данных типа FAR. ¦ ¦ ¦ ¦ +-------------------------+-------------------------------------+ ¦ .FARDATA? [имя] ¦ Эквивалентна UFARDATA. Действует¦ ¦ ¦ только в режиме MASM. ¦ L-------------------------+--------------------------------------

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



User-generated error


(Ошибка, сгенерированная пользователем)

Ошибка выдана в результате выполнения одной из директив ге- нерирования ошибки. Например:

.ERR ; попадание в это место является ошибкой

USES has no effect without language (USES игнорируется без спецификации языка)

Это предупреждающее сообщение выдается, если оператор USES используется без предварительной спецификации языка.



Условия выполнения прохода Ассемблером


Следующие директивы обеспечивают выполнение условного ас- семблирования или генерацию ошибки на основе текущего прохода Ас- семблера:

----------------------T-----------------------------------------¬ ¦ Директива IFxxx ¦ ассемблирует "тело_условия_true", если:¦ +---------------------+-----------------------------------------+ ¦ IF1 ¦ Турбо Ассемблер выполняет первый проход.¦ ¦ IF2 ¦ Турбо Ассемблер выполняет второй проход.¦ L---------------------+------------------------------------------

----------------------T-----------------------------------------¬ ¦ Директива ERRxxx ¦ генерирует ошибку user error, если: ¦ +---------------------+-----------------------------------------+ ¦ ERRIF1 ¦ Турбо Ассемблер выполняет первый проход.¦ ¦ ¦ ¦ ¦ .ERR1 ¦ Турбо Ассемблер выполняет первый проход¦ ¦ ¦ (только для режима MASM). ¦ ¦ ¦ ¦ ¦ ERRIF2 ¦ Турбо Ассемблер выполняет второй проход.¦ ¦ ¦ ¦ ¦ .ERR2 ¦ Турбо Ассемблер выполняет второй проход¦ ¦ ¦ (только для режима MASM). ¦ L---------------------+------------------------------------------

Обычно Турбо Ассемблер работает как однопроходный ассемблер. Если вы используете средство многопроходной работы Турбо Ассемб- лера (вызывая его с параметром командной строки /m), то при не- обходимости используется несколько проходов.

Поскольку Турбо Ассемблер всегда выполняет по крайней мере один проход, директива условного ассемблирования IF1 всегда будет ассемблировать код своего условного блока, а директивы .ERR1 и ERRIF1 всегда будут генерировать сообщение об ошибке (но только на первом проходе).

Если вы используете любую из этих директив и не разрешаете многопроходную работу, то Турбо Ассемблер будет генерировать для всех таких директив предупреждение "Pass dependent construction" ("Конструкция, зависящая от прохода"), чтобы предупредить вас о возможно опасном пропуске кода. Если вы разрешите многопроходную работу, Турбо Ассемблер будет выполнять точно два прохода и гене- рировать предупреждение Vaximum compatibility pass was done (Вы- полнен проход с целью обеспечения максимальной совместимости).



Условные директивы с идентификатором


Эти директивы обеспечивают условное ассемблирование или ге- нерацию сообщения об ошибке на основе того, является ли опреде- ленным один или более идентификаторов. Данные идентификаторы объ- единены в выражение с идентификаторами.

Выражение с идентификаторами - это выражение, состоящее из имен идентификаторов, булевских операций AND, OR, NOT и круглых скобок. В выражении с идентификаторами каждое имя идентификатора интерпретируется как булевское значение, при вычислении которого получается значение true, если идентификатор существует (опреде- лен), или false, если идентификатор не существует (даже если он определяется в модуле позднее). Турбо Ассемблер комбинирует эти значения, используя булевские операции, для получения конечного значения true или false. В своей простейшей форме выражение с идентификаторами содержит имя единственного идентификатора и дает при вычислении значение true, если этот идентификатор определен. Синтаксические правила в выражении с идентификаторами аналогичны тем, которые используются в выражениях Турбо Ассемблера. Напри- мер, если идентификатор foo определен, а идентификатор bar - нет, то при вычислении выражения с идентификаторами получаются следую- щие результаты:

Вычисление определенных и неопределенных идентификаторов

Таблица 15.3 ------------------------------------T---------------------------¬ ¦ Выражение с идентификаторами ¦ Результат ¦ +-----------------------------------+---------------------------+ ¦ foo ¦ True ¦ ¦ ¦ ¦ ¦ bar ¦ False ¦ ¦ ¦ ¦ ¦ not foo ¦ False ¦ ¦ ¦ ¦ ¦ not bar ¦ True ¦ ¦ ¦ ¦ ¦ foo OR bar ¦ True ¦ ¦ ¦ ¦ ¦ foo AND bar ¦ False ¦ ¦ ¦ ¦ ¦ NOT (foo AND bar) ¦ True ¦ ¦ ¦ ¦ ¦ NOT foo OR NOT bar ¦ True (то же, что ¦ ¦ ¦ (NOT foo) OR (NOT bar) ¦ L-----------------------------------+----------------------------

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

Директивы, использующие выражение с идентификаторами Таблица 15.4 -------------------------T--------------------------------------¬ ¦Директива IFxxx ¦ Ассемблирует "тело_условия_true" если¦ +------------------------+--------------------------------------+ ¦IFDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение true. ¦ ¦ ¦ ¦ ¦IFNDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение false. ¦ ¦ ¦ ¦ ¦ELSEIFDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение true. ¦ ¦ ¦ ¦ ¦ELSEIFNDEF выражение_ид ¦ при вычислении выражения получается¦ ¦ ¦ значение false. ¦ L------------------------+---------------------------------------



Условные директивы с текстовыми строками


Эти директивы условное ассемблирование или генерацию сообще- ний об ошибке на основе содержимого текстовой строки. Текстовой строкой может быть либо строка, заключенная в угловые скобки (<>), либо имя текстовой макрокоманды с предшествующим символом %. Например:

<ABC> ; текстовая строка ABC %foo ; содержимое текстовой макрокоманды foo

Примечание: Об определении текстовых макрокоманд и ра- боте с ними рассказывается в Главе 14.

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

Директивы условного ассемблирования, использующие текстовую строку Таблица 15.6 -----------------------T----------------------------------------¬ ¦ Директива IFxxx ¦ ассемблирует "тело_условия_true", если:¦ +----------------------+----------------------------------------+ ¦ IFNB текст_строка ¦ "текст_строка" не состоит из одних про-¦ ¦ ¦ белов. ¦ ¦ ¦ ¦ ¦ IFB текст_строка ¦ "текст_строка" не пуста. ¦ ¦ ¦ ¦ ¦ IFIDN текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ идентичны. ¦ ¦ ¦ ¦ ¦ IFINDI текст_строка_1¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ ,текст_строка_2 ¦ идентичны (регистр символов не учиты- ¦ ¦ ¦ вается. ¦ ¦ ¦ ¦ ¦ IFDIF текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ различны. ¦ ¦ ¦ ¦ ¦ IFDEFI текст_строка_1¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ ,текст_строка_2 ¦ различны (регистр символов игнорирует- ¦ ¦ ¦ ся. ¦ ¦ ¦ ¦ ¦ ELSEIFNB текст_строка¦ "текст_строка" не состоит из пробелов. ¦ ¦ ¦ ¦ ¦ ELSEIFB текст_строка ¦ "текст_строка" не пуста. ¦ ¦ ¦ ¦ ¦ ELSEIFIDN текст_стро-¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ ка_1, текст_строка_2¦ идентичны. ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ELSEIDNI текст_стро- ¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ ка_1,текст_строка_2 ¦ идентичны (регистр символов игнориру- ¦ ¦ ¦ ется). ¦ ¦ ¦ ¦ ¦ ELSEIFDIF текст_стро-¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ ка_1,текст_строка_2 ¦ различны. ¦ ¦ ¦ ¦ ¦ ELSEIFDIFI текст_стро¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ -ка_1,текст_строка_2¦ различны (регистр символов игнориру- ¦ ¦ ¦ ется). ¦ L----------------------+-----------------------------------------


Использующие текстовую строку директивы генерации сообщения об ошибке показаны в следующей таблице:

Директивы вывода сообщений об ошибке использующие текстовую строку Таблица 15.6 -------------------------T--------------------------------------¬ ¦Директива ERRxxx ¦ Генерирует сообщение об ошибке, если:¦ +------------------------+--------------------------------------+ ¦ERRIFNB текст_строка ¦ "текст_строка" не состоит из одних¦ ¦ ¦ пробелов. ¦ ¦ ¦ ¦ ¦.ERRIFNB текст_строка ¦ "текст_строка" не состоит из одних¦ ¦ ¦ пробелов (только для режима MASM). ¦ ¦ ¦ ¦ ¦ERRIFB текст_строка ¦ "текст_строка" состоит из пробелов. ¦ ¦ ¦ ¦ ¦.ERRB текст_строка ¦ "текст_строка" состоит из одних про-¦ ¦ ¦ белов. ¦ ¦ ¦ ¦ ¦ERRIFIDN текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ идентичны. ¦ ¦ ¦ ¦ ¦.ERRIDN текст_строка_1, ¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ идентичны (только для режима MASM). ¦ ¦ ¦ ¦ ¦ERRIFIDNI текст_строка_1¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ ,текст_строка_2 ¦ идентичны (регистр символов игнориру-¦ ¦ ¦ ется). ¦ ¦ ¦ ¦ ¦.ERRIDNI текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ идентичны (регистр символов игнориру-¦ ¦ ¦ ется) - только для режима MASM. ¦ ¦ ¦ ¦ ¦ERRIFDIF текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ различны. ¦ ¦ ¦ ¦ ¦.ERRDIF текст_строка_1, ¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ различны (только для режима MASM). ¦ ¦ ¦ ¦ ¦ERIFDIFI текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ различны (регистр символов игнориру- ¦ ¦ ¦ ется). ¦ ¦ ¦ ¦ ¦.ERRFIFI текст_строка_1,¦ "текст_строка_1" и "текст_строка_2" ¦ ¦ текст_строка_2 ¦ различны (регистр символов игнориру- ¦ ¦ ¦ ется) - только для режима MASM. ¦ L------------------------+---------------------------------------



Используйте эти директивы для проверки передаваемых макроко- мандам аргументов (однако их можно использовать не только в мак- рокомандах).

При использовании их в макроопределениях директивы IFB и IFNB позволяют определить, передали ли вы в макрокоманду нужное число аргументов. Если при вызове макрокоманды вы передали слиш- ком мало аргументов, Турбо Ассемблер не генерирует сообщение об ошибке. Незаданные аргументы просто остаются пустыми. Таким обра- зом, вы можете определить макрокоманду, воспринимающую переменное число аргументов. Например:

. . . load MACRO addr, reg IFNB <reg> MOV reg,addr ELSE MOV ax,addr ENDIF ENDM . . .

Вы можете вызывать макрокоманду данного примера, как load test,cx, что даст генерацию инструкции mov cx,test, или вызвать ее как load test, то приведет к генерации инструкции mov ax,test, поскольку второй параметр пуст. Можно также использовать директи- ву ERRIFB для генерации сообщения об ошибке, если в вызове макро- команды пропущен аргумент:

. . . load MACRO addr ERRIFNB <addr> MOV reg,addr ENDM . . .

Если эту макрокоманду вызвать с помощью load, а не с помощью load test, то будет генерироваться ошибка.


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


Эти директивы обеспечивают условное ассемблирование или ге- нерацию сообщений об ошибке на основе результатов вычисления в Турбо Ассемблере выражения. Во всех этих директивах при вычисле- нии выражения должна получаться константа, и оно не может содер- жать опережающих ссылок. Если при вычислении выражения получается 0, Турбо Ассемблер рассматривает выражение, как ложное (false). в противном случае оно рассматривается как истинное (true).

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

Директивы условного ассемблирования, использующие сообщения Таблица 15.1 ----------------------T-----------------------------------------¬ ¦ Директива IFxxx ¦ Ассемблирует "тело_условия_true" если: ¦ +---------------------+-----------------------------------------+ ¦ IF выражение ¦ при вычислении выражения получается ¦ ¦ ¦ значение true. ¦ ¦ ¦ ¦ ¦ IFE выражение ¦ при вычислении выражения получается ¦ ¦ ¦ значение false. ¦ ¦ ¦ ¦ ¦ ELSEIF выражение ¦ при вычислении выражения получается ¦ ¦ ¦ значение true. ¦ ¦ ¦ ¦ ¦ ELSEIFE выражение ¦ при вычислении выражения получается ¦ ¦ ¦ значение false. ¦ L---------------------+------------------------------------------

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

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

Таблица. 15.2 ---------------------T------------------------------------------¬ ¦ Директива ERRxxx ¦ Генерируется сообщение user error, если: ¦ +--------------------+------------------------------------------+ ¦ ERRIF выражение ¦ при вычислении выражения получается зна- ¦ ¦ ¦ чение true. ¦ ¦ ¦ ¦ ¦ .ERRNZ выражение ¦ при вычислении выражения получается зна- ¦ ¦ ¦ чение true (только в режиме MASM). ¦ ¦ ¦ ¦ ¦ ERRIFE выражение ¦ при вычислении выражения получается зна- ¦ ¦ ¦ чение false. ¦ ¦ ¦ ¦ ¦ .ERRE выражение ¦ при вычислении выражения получается зна- ¦ ¦ ¦ чение false (только в режиме MASM). ¦ L--------------------+-------------------------------------------



Установка Турбо Ассемблера в системе


Перед тем, как познакомиться с программированием на Турбо Ассемблере, вам нужно сделать следующее. Возьмите дистрибутивные диски Турбо Ассемблера и сделайте для каждого из них (с помощью утилиты DOS) рабочую копию. После этого исходные (дистрибутивные) диски уберите в надежное место.

Если собираетесь использовать Турбо Ассемблер вместо MASM (макроассемблер фирмы Microsoft), прочитайте Главу 2 и посмотри- те, в чем поведение Турбо Ассемблера отличается от MASM.

На диске INSTALL находится программа INSTALL.EXE, которая поможет вам установить Турбо Ассемблер версии 3.0 в вашей систе- ме. При установке следует учесть два параметра:

1. Hard Disk Users (пользователям системы с жестким диском): этот параметр позволяет выбрать подкаталоги, в которые будут загружены файлы.

2. Floppy Disk Users (пользователям системы с гибкими диска- ми): этот параметр установит файлы, необходимые для рабо- ты Турбо Ассемблера, в системе с двумя дисководами для гибких дисков. До начала работы подготовьте четыре отфор- матированных диска. Для начала установки перейдите в каталог с программой INSTALL и наберите команду:

INSTALL

Вам будут даны инструкции относительно каждого приглашения в рамке в нижней части экрана установки.

При запуске INSTALL в системе портативного компьютера или в любой другой системе с жидкокристаллическим дисплеем запуск INSTALL следует выполнять с параметром /b, который позволяет пе- ревести систему в черно-белый режим:

INSTALL /b



Устранение неиспользуемого кода


В Турбо Паскале имеются средства, обеспечивающие устранение неиспользуемого кода. Это означает, что в полученный в результате файл .EXE не будет включаться код процедур и функций, который ни- когда не выполняется. Но поскольку нет полной информации о содер- жимом модулей Турбо Ассемблера, Турбо Паскаль может выполнять для них только ограниченную оптимизацию.

Турбо Паскаль будет устранять код модуля .OBJ в том и только в том случае, если к любой доступной процедуре или функции этого модуля нет обращения. Если же на какую либо процедуру или функцию имеется ссылка, то весь этот модуль используется.

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



Утилита-преобразователь H2ASH


Модули Си и С++ в программе обычно совместно используют оп- ределение типов и структур данных. Это делается с помощью включения небольших файлов (файлов-заголовков), которые содержат определения типов и структуры данных, используемые в нескольких модулях. Файл заголовка в Си/С++ имеет обычно имя с расширением .H. Ассемблируемые модули обычно имеют файлы заголовков с расшире- нием .ASH (или .INC).

Программы, содержащие модули, написанные на Си/С++ и модули Турбо Ассемблера, должны иметь возможность совместного определе- ния типов и структур данных. Этому способствует утилита H2ASH.

Утилита H2ASH преобразует файлы заголовков Си/С++ в файлы заголовков языка Ассемблера. Как и исходные файлы с расширением .H полученные в результате файлы с расширением .ASH сами не со- держат программу. Если для вызова H2ASH вы используете следующий синтаксис:

H2ASH [[параметры] <имя_файла> [<имя_файла> .]]

где каждое поле "имя_файла" задает имя конвертируемого файла за- головка. Утилита H2ASH предполагает, что преобразуемый файл имеет по умолчанию расширение .H. Для каждого обрабатываемого файла со- ответствующий выходной файл имеет расширение .ASH.

"Параметры" соответствуют параметрам командной строки компи- лятора Borland C++, а также специфическим параметрам утилиты H2ASH (которые соответствуют параметрам -q Турбо Ассемблера). См. "Руководство пользователя Bоrland C++" и оперативный справочник, где можно найти описания данных параметров.

Утилита H2ASH преобразует следующие конструкции:

- все основные типы языка Си;

- типы ENUM (в типы ENUM TASM);

- #IFDEF (в эквивалентные IFDEF Ассемблера);

- #DEFINE (в определения EQU);

- структуры и объединения (в структуры и объединения Турбо Ассемблера);

- структуры с битовыми полями (в записи Ассемблера RECORD);

- определения TYPEDEF (в TYPEDEF Ассемблера);

- классы без множественного наследования и без виртуальных базовых классов;

- элементы классов;

- переопределения операций.

Утилита-преобразователь имеет следующие ограничения:


- весь преобразуемый код игнорируется, выполняемый код не генерируется;

- директивы #INCLUDE в выходных файлах полностью расширяются;

- в выводе Ассемблера может возникнуть конфликт имен, так как правила области действия С++ существенно отличаются от правил Ассемблера (помочь здесь может использование режима Ideal);

Преобразователь H2ASH не только облегчает организацию интер- фейса между С/С++ и языком Ассемблера (с максимальной производи- тельностью). H2ASH автоматически преобразует описания базовых классов С++ в эквивалентные объектные описания Ассемблера и опре- деляет "нескорректированные" имена методов. При записи базового класса на языке Ассемблера мы рекомендуем вам использовать следу- ющую процедуру:

1. Написать описание класса в файле заголовка языка Си.

2. Включить описание файла заголовка Си во все классы-потом- ки и модули на языке Си, которые используют этот базовый класс.

3. Используйте преобразователь H2ASH для файла заголовка с целью получения объектного файла заголовка Ассемблера (этот процесс можно автоматизировать с помощью формирую- щего файла).

4. Включите объектный файл заголовка Ассемблера в модуль, где записаны методы на языке Ассемблера.

Более подробную информацию об утилите H2ASH можно найти в текстовых файлах документации на дисках Турбо Ассемблера.

Назад | Содержание | Вперед


Value out of range


(Значение константы превышает допустимое значение)

Константа представляет собой, вообще говоря, число правиль- ного формата. Однако ее значение превышает допустимую в данном конкретном случае величину. Например:

DB 400



Ваша первая программа на Турбо Ассемблере


В программировании первой программой традиционно является программа, выводящая на экран сообщение "Привет!". Не будет иск- лючением и наша программа, поскольку это является хорошей отправ- ной точкой.

Войдите в текстовый редактор (один из тех редакторов, кото- рые формируют файлы в коде ASCII) и введите следующие строки программы под названием HELLO.ASM:

.MODEL SMALL .STACK 100h .DATA Message DB 'Привет!',13,10,'$' .CODE mov ax,@Data mov ds,ax ; установить регистр DS таким ; образом, чтобы он указывал ; на сегмент данных mov ah,9 ; функция DOS вывода строки mov dx,OFFSET Message ; ссылка на сообщение "Привет!" int 21h ; вывести "Привет!" на экран mov ah,4ch ; функция DOS завершения ; программы int 21h ; завершить программу END

После того, как вы введете эту программу, сохраните ее на диске.

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



Ваша вторая программа на Турбо Ассемблере


Теперь вы готовы к тому, чтобы ввести и запустить программу, которая действительно что-то делает. Вернитесь в текстовый редак- тор и введите следующую программу REVERSE.ASM:

.MODEL SMALL .STACK 100h .DATA MAXIMUM_STRING_LENGTH EQU 1000 StringToReverse DB MAXIMUM_STRING_LENGTH DUP (?) ReverseString DB MAXIMUM_STRING_LENGTH DUP (?) .CODE mov ax,@Data mov ds,ax ; установить регистр DS таким ; образом, чтобы он указывал mov ah,3fh ; функция DOS чтения ввода mov bx,0 ; описатель стандартного ввода mov cx,MAXIMUM_STRING_LENGTH ; считать до максималь- ; ного числа символов mov dx,OFFSET StringToReverse ; сохранить строку int 21h ; получить строку and ax,ax ; были считаны символы? jz Done ; нет, конец mov cx,ax ; поместить длину строки в ; регистр СХ, который можно ; использовать, как счетчик push cx ; сохранить в стеке длину ; строки mov bx,OFFSET StringToReverse mov si,OFFSET ReverseString add si,cx dec si ; указывает на конец буфера ; строки ReverseLoop: mov al,[bx] ; получить следующий символ mov [si],al ; сохранить символы в ; обратном порядке inc bx ; указатель на следующий ; символ dec si ; указатель на предыдущую ; ячейку buffer loop ReverseLoop ; переместить следующий ; символ, если он имеется pop cx ; извлечь длину строки mov ax,40h ; функция записи DOS mov bx,1 ; описатель стандартного ; вывода mov dx,OFFSET ReverceString ; напечатать строку Done: mov ah,4ch ; функция DOS завершения ; программы int 21h ; завершить программу END

Скоро вы увидите, что сможет делать эта программа. Для нача- ла не забудьте ее сохранить (под именем REVERSE.ASM).



Вещественные значения


Параметры-значения вещественного типа (real) передаются, как 6 байт в стеке (в Турбо Паскале это тип представляет собой 6-бай- товый программно-эмулируемый тип с плавающей точкой). Это единс- твенный тип, превышающий 4 байта, который может передаваться че- рез стек.



Включение библиотеки


В том случае, когда вы знаете, что ваш исходный файл будет всегда использовать подпрограммы заданной библиотеки, можно ис- пользовать директиву INCLUDELIB. Директива INCLUDELIB сообщает компоновщику, что нужно включить указанную библиотеку. В режиме Ideal эта директива имеет следующий синтаксис:

INCLUDELIB "имя_файла" ; обратите внимание на кавычки!

а в режиме MASM:

INCLUDELIB имя_файла

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

Приведем пример:

INCLUDELIB "diskio" ; включает DISKIO.LIB

Назад | Содержание | Вперед



Включение комментариев в тело макрокоманды


В особенно сложных макрокомандах иногда желательно поместить в теле макрокоманды комментарии, которые не должны включаться при ее расширении. Это также уменьшает объем необходимой Турбо Ас- семблеру для обработки макрокоманд памяти. Для этого используйте комментарий с предшествующей двойной точкой запятой (в начале строки). Например, следующее тело макрокоманды:

;; Это макрокоманда с комментарием DB 'макрокоманда с комментарием'

приведет к включению при ее вызове только следующего текста:

DB 'макрокоманда с комментарием'

Примечание: Комментарии с одиночной точкой с запятой при вызове макрокоманды всегда включаются в макрорасшире- ние.