Загрузка...

Глава 11. Режим Turbo Assembler Ideal.


Для тех из вас, кому необходимо иметь в своем распоряжении и
MASM, данная глава, возможно, окажется самой важной главой в
данном руководстве. Помимо практически точной совместимости с
синтаксисом MASM, Turbo Assembler позволяет сглаживать все
проблемы и неровности, связанные с программированием на языке
ассемблера, при помощи производной MASM, именуемой режимом Ideal.

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

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

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

Что такое режим Ideal?
——————————————————————

Режим Turbo Assembler Ideal вводит новый синтаксис операндов
выражений и команд. Этот не является радикально отличным от
существующего синтаксиса MASM, однако в режиме Ideal операции и
ключевые слова MASM реализованы более просто и ясно, а
используемые им формы более информативны, как для вас, так и для
Turbo Assembler.

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

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

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

— Возможность иметь одинаковые имена членов нескольких структур.

— Сложные выражения HIGH и LOW.

— Предсказуемая обработка EQU.

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

— Улучшенная непротиворечивость директив.

— Хорошо читаемая запись выражений в скобках.

Зачем использовать режим Ideal?
——————————————————————

Для использования режима Turbo Assembler Ideal существует
множество веских причин. Если вы только еще изучаете язык
ассемблера, то режим Ideal легко позволит вам конструировать
выражения и операторы, которые будут делать именно то, что вы
желаете. Вам не придется наугад пробовать различные способы, пока
случайно не найдется команда, выполняющая желаемое. Если же вы
имеете большой опыт программирования на ассемблере, то вы можете
использовать средства режима Ideal для написания сложных программ,
применяя такие расширения языка, как вложенные структуры и
объединения.

Прямым преимуществом более ясного синтаксиса режима Ideal
является то, ассемблирование файлов в данном случае выполняется на
30% быстрее, чем в режиме MASM. Чем больше по размеру
разрабатываемые вами проекты и файлы, тем больше выигрыш от
переключения на режим Ideal.

Строгие правила контроля типа данных, применяемые в режиме
Ideal, позволяют Turbo Assembler обнаруживать ошибки, которые в
противном случае выявлялись бы во время выполнения или при отладке
программы. Это аналогично тому, как компиляторы языков высокого
уровня помогают вам , указывая на сомнительные конструкции и
несоответствующие друг другу размеры данных.

Хотя для некоторых выражений режим Ideal использует несколько
отличающийся синтаксис, вы тем не менее имеете возможность писать
программы, которые будут одинаково хорошо ассемблироваться как в
режиме MASM, так и в режиме Ideal. Кроме того, в пределах одного и
того же файла можно сколько угодно раз переключаться между
режимами MASM и Ideal. Это особенно полезно для экспериментов со
свойствами режима Ideal, либо во время преобразования к режиму
Ideal существующих программ, написанных по правилам синтаксиса
MASM. Переключение на режим Ideal может быть выполнено для новой
части программы, добавляемой к существующим исходным файлам,
созданным в режиме MASM, для обеспечения полной совместимости с
ними.

Вход и выход из режима Ideal
——————————————————————

Для переключения между режимами Ideal и MASM служат директивы
IDEAL и MASM. Turbo Assembler всегда начинает ассемблирование
исходного файла, установив режим MASM. Для переключения на режим
Ideal следует перед тем, как использовать какиелибо средства этого
режима, включить в исходный файл директиву IDEAL. Начиная с этого
места, пока не встретится директива MASM, все операторы ведут себя
согласно описаниям, приводимым в настоящей главе. Переходить от
режима MASM к Ideal и обратно можно сколько угодно раз и в любых
частях исходного файла. Вот пример:

DATA SEGMENT ;начало в режиме MASM
abc LABEL BYTE ;abc адресует xyz как байт
xyz DW 0 ;определение слова в метке xyz
DATA ENDS ;конец сегмента данных
IDEAL ;переключение на режим Ideal
SEGMENT CODE ;ключевое слово SEGMENT теперь стоит
;первым
PROC MyProc ;ключевое слово PROC также теперь
;стоит первым
.
. ;здесь следует программа в режиме Ideal
.
ENDP MyProc ;факультативное повторение метки MyProc
ENDS ;факультативное повторение имени
;сегмента
MASM ;переключение назад, на режим MASM
CODE SEGMENT ;теперь требуется задавать имя до
;ключевого слова SEGMENT
Func2 PROC ;теперь требуется задавать имя
;до ключевого слова PROC
.
. ;здесь следует программа в режиме MASM
.
IDEAL ;снова переключение на режим Ideal!
.
. ;здесь следует программа в режиме Ideal
.
MASM ;снова переключение на режим MASM,
;у вас голова не закружилась?
Func2 ENDP ;перед ключевым словом опять требуется
;имя
CODE ENDS ;здесь тоже опять нужно имя

Вы видите, что в режиме Ideal ключевые слова директив, такие
как PROC и SESMENT, следуют перед идентифицирующими их
символическими именами, в порядке, обратном режиму MASM. Кроме
того, повторение имени сегмента или процедуры после директив ENDP
и ENDS необязательно. Использование этого имени в данном случае
позволяет сделать программу более ясной, так как идентифицирует
заканчивающиеся сегмент или процедуру. Это хорошая практика
программирования, особенно в случае программ с несколькими
вложенными сегментами и процедурами. Однако, помещать после
директив ENDP и ENDS символические имена в обязательном порядке не
требуется.

Различия между режимами MASM и Ideal
——————————————————————

В данном разделе описаны основные различия между режимами
MASM и Ideal. Если вы знакомы с MASM, вам может захотеться
поэкспериментировать с отдельными средствами, преобразовав
небольшие участки ваших существующих программ в режим ideal.
Помните о необходимости ограничить выделяемые участки ключевыми
словами IDEAL и MASM. Следуя этой схеме, своего рода методу
обучения режиму Ideal по ходу практической деятельности, вы можете
ассемблировать ваши текущие программы без необходимости пересмотра
каждой команды с точки зрения использования специальных средств
режима Ideal. Разумеется, в конце концов вы можете захотеть
полностью перейти к работе исключительно в режиме Ideal. Либо вы
пожелаете чередовать и согласовывать модули в режимах MASM и
Ideal. Выбор за вами.

Лексемы режима Ideal ——————————————

Turbo Assembler считывает и понимает вашу программу, разделяя
для этого ее текст на отдельные слова или символические имена,
которые называются лексемами. Примеры лексем включают в себя
метки, такие как VALUE, NAME или AGE, а также другие символические
имена, числа, части выражений и арифметические операции типа +, -,
* и /.

Два типа лексем, а именно символические имена и числа с
плавающей точкой, в режиме Ideal имеют несколько отличные формы.
Как описано далее, эти изменения позволяют разрешить некоторые
неоднозначности синтаксиса MASM.

Лексемы — символические имена
——————————

В случае символических имен режима Ideal в качестве части
символического имени не разрешается использовать точку (.). Точку
можно использовать лишь в качестве операции члена структуры или в
числе с плавающей точкой.

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

Pennies DW 0
STRUC Heaven
Dimes DW ?
Nickels DW ?
Pennies DW ? ;конфликта между именами не возникает
ENDS
Take Heaven <>

В данном примере показано создание переменной с тремя полями,
Dimes, Nickels и Pennies, составляющим структуру с именем Heaven.
Поля Dimes и Nickels данной структуры уникальны. Однако, имя
Pennies встречается дважды, сначала вне структуры, а затем в самой
сруктуре Heaven.

Данный пример демонстрирует, что одно и то же имя Pennies
может использоваться как внутри структуры, так и вне ее, не
вызывая конфликта, что в MASM невозможно.

Переменная Pennies вне структуры Heaven отличается оы члена
структуры с именем Pennies. Следовательно, для ссылки на имя члена
структуры, которое дублируется вне структуры, требуется три
элемента: имя структуры, точка и имя члена структуры. В данном
примере Take.Pennies приравнивает смещение поля Pennies внутри
Heaven. Отдельно же взятое имя Pennies приравнивает смещение
переменной, которая находится вне структуры.

Дублирующиеся имена членов структур
————————————

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

STRUC SomeStuff
Size DW ?
Flag DW ?
Amount DW ?
ENDS

STRUC OtherStuff
Size DW ? ;конфликт не возникает ни здесь,
Amount DW ? ;ни здесь
ENDS

Лексемы — числа с плавающей точкой
———————————-

В режиме Ideal десятичные числа с плавающей точкой должны
всегда в ключать в себя точку (.):

FP DT 1.0e7 ;значение с плавающей точкой в режиме Ideal

Данная запись определяет 1-байтовое значение с плавающей
точкой с именем FP, равное 1.0e7. В режиме MASM приемлема
следующая, хотя и менее ясная, форма:

FP DT 1E7 ;значение с плавающей точкой в режиме MASM

Такая форма записи может показаться вполне
удовлетворительной, однако рассмотрим, что случится, если в
предшествующей части программы вы использовали команду .RADIX 16,
изменившую систему счисления, принимаемую по умолчанию, с
десятичной на шестнадцатиричную. В данном случае результат будет
ужасным, так как в режиме MASM данное число с плавающей точкой
будет ассемблировано как шестнадцатиричное число 01E7! Требуя от
вас обязательного использования десятичной точки, режим Ideal тем
самым исключает возможность случайно спутать числа с плавающей
точкой и шестнадцатиричные числа.

Директивы EQU и = ———————————————

Определения EQU, также называемые приравниваниями, в режиме
Ideal всегда рассматриваются как текстовые. В режиме MASM
приравнивания в некоторых случаях рассматриваются как текстовые, а
в других как числовые. Рассмотрим следующие примеры:

;Объявление нескольких приравниваний
A = 4
B = 5
C EQU B + A
B = 6

;Объявление переменной
V DW C ;в режиме MASM 9, а в режиме Ideal 10

При обработке выражения EQU MASM оценивает B + A. В данном
случае А равно 4, а B равно 5; следовательно, C равно 9. Режим
Ideal обрабатывает то же выражение иначе, записывая все, что идет
вслед за директивой EQU, в строковой форме, в данном случае B + A.
Далее режим Ideal выполняет подстановку данной строки везде, где
используется C. В данном примере, поскольку оценка выражения была
отложена до объявления переменной V и поскольку выше B была
переопределена в значение 6, в то режиме Ideal переменная V равна
10 (6+4).

В режиме Ideal EQU всегда служит для определения строки
символов. Знак равенства (=) всегда определяет вычисляемое
выражение. Это правило легче запомнить, если представить себе
визуально, что знак равенства (=) всегда немедленно расчитывает
выражения, а EQU откладывает расчет выражения до того места
программы, где использовано имя константы. Между прочим, многие
рассматривают данное свойство как «раннее» и «позднее» связывание
имен со значениями.

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

Самое значительное различие между выражениями в режимах Ideal
и MASM состоит в том, каким образом в этих режимах работают
квадратные скобки. В режиме Ideal квадратные скобки всегда
обозначают ссылку на содержимое, определяемое взятым в скобки
числом. Квадратные скобки здесь никогда не выполняют неявных
операций сложения. Следовательно, в режиме Ideal многие
стандартные конструкции MASM недопустимы.

Операция квадратные скобки []
——————————

В режиме Ideal квадратные скобки должны быть всегда
использованы для приема содержимого некоторого элемента. Например,

mov ax,wordptr

вызовет вывод на дисплей сообщения уровня предупреждения.
Дело в том, что вы пытаетесь загрузить в регистр (AX) указатель
(wordptr). Правильной формой записи является

mov ax,[wordptr]

тем самым в AX просто загружается содержимое адреса памяти,
на который указывает wordptr (в текущем сегменте данных,
определяемом DS).

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

mov ax,OFFSET wordptr

Примеры операндов
——————

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

mov ax,[bx][si] ;режим MASM

В режиме Ideal такая запись вызовет синтаксическую ошибку.
Если квадратные скобки задают содержимое памяти, то получится, что
данная команда должна загрузить в AX одновременно значение,
адресуемое BX, плюс значение, адресуемое SI. Разумеется, ничего
такого выполнено быть не может. Вы, очевидно, имели в виду, и
Turbo Assembler требует следующее:

mov ax,[bx+si] ;режим Ideal

Теперь данная команда вполне ясна. В AX загружается
содержимое адреса памяти со смещением OFFSET BX+SI относительно
текущего сегмента данных, адресуемого DS. (Поскольку AX — это
16-битовый регистр, то и размер адресуемой памяти представляет
собой 16-битовое слово. Если заменить AX на AL, или другой 8-
битовый регистр, то размером адресуемой памяти будет являться
байт.) Ниже приводится аналогичный пример:

mov ax,es:[bx][si] ;режим MASM

Это также вызовет в режиме Ideal ошибку. Можно описать такую
запись как: «выполнить переопределение сегмента ES: для значения,
адресуемого BX, и все вместе сложить с содержимым памяти,
адресуемой SI, загрузив результат (любой) в AX». Эта запись,
разумеется, бессмысленна, и вы имели в виду:

mov ax,[es:bx+si] ;режим Ideal

Хорошо! Данная запись складывает сегменты BX и SI, задавая
вместо сегмента данных по умолчанию DS переопределение сегментного
регистра ES, относительно которого и рассматривается данная сумма.
В AX загружается 16-битовое содержимое этого адреса памяти. Вот
еще один пример MASM, ранее вам часто встречавшийся

mov ax,6[bx] ;режим MASM

Математику может показаться, что данная команда умножает на 6
значение содержимого памяти, адресуемой BX. Либо, что это —
некоторый не описанный в данной документации способ индексации
массива, или, может быть, просто опечатка? Нет, это ни одно и не
другое, ни третье, как показывает соответствующая форма в режиме
Ideal:

mov ax,[bx+6] ;режим Ideal

Разумеется! Вам требуется загрузить в AX содержимое памяти из
текущего сегмента данных в шести байтах от адреса смещения,
задаваемого BX. Яснее это не запишешь. В режиме MASM, однако,
запись не всегда столь же ясна:

mov ax,es:[bp+8][si+6] ;режим MASM

Посмотрим; вы берете значение в 8 байтах от BP, выполняете
переопределение сегмента ES: и … нет, переопределение должно
действовать для значения в 6 байтах от SI. Но нет, это
неправильно, может быть, вы берете значение в BP+8, складываете с
содержимым [SI+6], выполняете переопределение и … Ох, забутьте
об этом! Режим Ideal делает данный и прочие сложные операнды
простыми как для чтения, так и для записи:

mov ax,[es:bp+si+14] ;режим ideal

Очевидно, что значение, расположенное в сегменте ES со
смещением BP+SI+14, загружается в AX, это ясно и очевидно. Верьте
или не верьте, но есть и еще аналогичные случаи:

mov al,byte ptr [bx] ;режим MASM

MASM позволяет задавать содержимое адресов памяти байтовыми
указателями, по крайней мере кажется, что данная команда именно
это и делает. Разумеется, вы можете указывать на байты или слова
только при помощи указателей (регистров или меток), что становится
совершенно ясным в случае режима Ideal:

mov al,[byte ptr bx] ;режим Ideal

Очевидно, что вы сообщаете Turbo Assembler о том, что BX —
это байтовый указатель, загружая в AL байт, расположенный в BX
байтах от начала текущего сегмента данных. Еще один пример, и
достаточно:

rep movs byte ptr [di],[si] ;режим MASM

Может показаться, что MASM позволяет преобразование символов,
адресуемых DI (и может быть, SI?) в байтовые указатели.
Разумеется, это невозможно. Вы, безусловно, имели в виду
следующее, и именно эта форма требуется для режима Ideal:

rep movs [byte ptr di], [byte ptr si] ;режим Ideal

Хотя такая запись и длиннее, но зато для команды MOVS она
явно задает регистры DI и SI в качестве байтовых указателей.

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

Операции ——————————————————

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

(Список приоритетов операций и полное их описание для режимов
MASM и Ideal см. в главе 2 Справочного руководства.)

Использование точек для записи членов структур
———————————————-

Для точного задания членов структур, к которым выполняется
обращение, используется операция члена структуры точка (.),
которая в режиме Ideal имеет более строгие правила записи.
Выражение справа от точки должно являться именем члена данной
структуры. В случае приведенных выше примеров структур SomeStaff и
OtherStaff загрузка регистров значениями конкретных членов этих
структур выполняется следующим образом:

;Объявление структур с использованием типов структур
S_Stuff SomeStuff <>
O_Stuff OtherStuff <>
mov ax,[S_Stuff.Amount] ;загрузка значения размером в слово
mov bl,[O_Stuff.Amount] ;загрузка значения размером в байт

Указатели структур
——————

Часто вам может понадобиться использовать регистр, содержащий
адрес структуры; другими словами, смещение в памяти первого байта
структуры. Либо адресацию структуры может выполнять переменная
памяти. В этих случаях для обращения к конкретному члену структуры
по имени вы должны сообщить Turbo Assembler о том, к которой
именно структуре вы в данном случае ссылаетесь:

mov cx,[(SomeStuff ptr bx).Amount]

Это позволяет Turbo Assembler знать, что BX является
указателем структуры SomeStuff, и что вы желаете загрузить поле
этой структуры Amount в регистр CX. Круглые скобки требуются
вследствие того, что операция точка (.) имеет более высокий
приоритет, нежели PTR. Без круглых скобок режим Ideal попытается
связать Amount с BX, что невозможно, так как регистры не могут
иметь уточняющих имен полей. Только структуры могут иметь
связанные с ними имена полей, и следовательно, до того, как
обратиться к полям структур, адресуемым регистрами, вы должны
выполнить преобразование указателей структур.

Операция SYMTYPE
—————-

Поскольку в режиме Ideal символическое имя не может
начинаться с точки, операция .TYPE режима MASM в режиме Ideal
называется SYMTYPE (см. главу 1 Справочного руководства.) Несмотря
на изменение имени, данная директива работает в обоих режимах
совершенно идентично, возвращая значения, указывающие на типы
различных символических имен:

Abyte DB 0
Aword DW 0
Array DD 20 DUP (8)
Btype = SYMTYPE Abyte ;1
Wtype = SYMTYPE Aword ;2
Atype = SYMTYPE Array ;4

Операции HIGH и LOW
——————-

В режиме Ideal операции HIGH и LOW имеют два значения. Обычно
операция HIGH задает старший (наиболее значащий) байт константы, а
LOW задает младший (наименее значащий) байт, как например:

MaxVal = 1234h
mov ah, HIGH MaxVal ;загружает в AH 12h
mov al,LOW MaxVal ;загружает в AL 34h

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

WordVal DW 0
DblVal DD 0
QVal DQ 0
mov bl, [BYTE LOW WordVal]
mov ax, [WORD HIGH DblVal]
mov ax, [WORD LOW Qval]

Первая команда MOV загружает в BL младший байт 2-байтового
слова, помеченного как WordVal. Вторая команда MOV загружает в AX
старшее слово 4-байтового значения, хранимого в DblVal. Третья
команда MOV загружает в AX младшее слово 8-байтового (учетверенное
слово) значения QVal. Отметим, что синтаксис здесь тот же, что и
для операции PTR, и ключевые слова BYTE или WORD расположены перед
операциями LOW или HIGH, плюс выражение адресации памяти.

Вы можете также использовать HIGH и LOW в комбинации, для
извлечения из многобайтового значения именно необходимой вам
информации:

DVal DD 12345678h
mov al,[BYTE LOW WORD HIGH DVal] ;загружает 34h в AL

В комбинации с BYTE и WORD ключевые слова LOW и HIGH
позволяют извлекать байты и слова из любой позиции в переменной.
Здесь DVal — это двойное слово, или 4-байтовое число. Для лучшего
понимания такого рода сложных комбинаций следует читать такие
выражения слева — направо. В данном случае команда mov загружает в
AL «младший байт (BYTE LOW) старшего слова (WORD HIGH) DVal.»

Необязательная операция PTR
—————————

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

[BYTE PTR OverTheRainbow]

в режиме Ideal можно сокращенно записать как

[BYTE OverTheRainbow

Операция SIZE
————-

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

theTitle DB «The Sun Also Rises»
TheAuthor DB «Ernest Hemingway»,0
titleSize = SIZE theTitle ;Ideal—18, MASM—1
authorSize = SIZE theAuthor ;Ideal—16, MASM—1

В данном примере theTitle и theAuthor — это строки символов.
В режиме MASM операция SIZE приравнивает длину (LENGTH) имени,
умноженную на ее тип (TYPE). LENGTH равна числу распределенных
элементов данных, в данном случае 1. (Даже если строка состоит из
нескольких символов, LENGTH рассматривает строки как однобайтовые
элементы, поскольку они определены директивой DB.) Значение TYPE в
случае DB также равно 1. Следовательно, в режиме MASM и titleSize,
и authorSize равны 1, что ничего не дает с точки зрения
определения длины строки.

В режиме Ideal операция SIZE возвращает число байтов, занятых
первым элементом после выполнения таких директив распределения
памяти, как DB или DW. Вследствие этого titleSize равно числу
символов в theTitle. Аналогичным образом, authorSize равно числу
символов в строке theAuthor. Однако, отметим, что theAuthor
оканчивается нулевым байтом, обозначающим конец строки. SIZE не
учитывает этот байт, возвращая только число символов в
предшествующей ему строке. Действительно, SIZE возвращает длину
только первого элемента из списка нескольких значений. Например,

CountDown DB 9,8,7,6,5,4,3,2,1,»Blast off»
TwoLines DB «First line», 13, 10, «Second line»
CDsize = SIZE CountDown ;1
TLsize = SIZE TwoLines ;10

Здесь CountDown адресует 9-байтовое значение, за которым
следует строка «Blast off». Однако, даже в этом случае SIZE для
CountDown (CDSize) в обоих случаях равна 1, т.е. размеру первого
элемента в списке. Это не выполняется для второго примера,
TwoLines, который представляет собой типичный способ хранения двух
строк, разделенных символами ASCII возврата каретки (13) и
перевода строки (10). Однако в данной программе они обозначены
одной и той же меткой, TwoLines. SIZE опять возвратит размер
первого элемента последовательности, в данном случае строки «First
line». В режиме Ideal TLSize равно 10, или числу символов в
строке. В режиме MASM TLSize равно 1, размеру первого элемента в
директиве DB, равному одному байту (символу).

Директивы ——————————————————

Функции директив в режиме Ideal идентичны, а имена по большей
части те же, что и у их эквивалентов в режиме MASM. Однако, между
аналогичными директивами в обоих режимах имеется ряд важных
различий, показанных в данном разделе.

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

Поскольку в режиме Ideal символическое имя не может
начинаться точкой (.), то в нем все директивы управления листингом
режима MASM должны начинаться со знака процента (%). Кроме того,
несколько имен было изменено таким образом, чтобы они более точно
описывали управляемые ими операции. В следующей таблицы показаны
соответствующие директивы управления листингом для обоих режимов:

——————————
Режим MASM Режим Ideal
——————————
.CREF %CREF
.LALL %MACS
.LFCOND %CONDS
.LIST %LIST
.SFCOND %NOCONDS
.XALL %NOMACS
.XCREF %NOCREF
.XLIST %NOLIST
——————————

Поскольку в режиме Ideal все директивы управления листингом
начинаются знаком процента (%), то директива режима MASM %OUT в
режиме Ideal записывается как DISPLAY:

DISPLAY «Starting to Assemble I/O Driver»

Директивы, начинающиеся точкой (.)
———————————-

Для ясности прочие директивы MASM, начинающиеся точкой,
переименованы. Например, все директивы управления типом
процессора, такие как .286, которые больше похожи на число, чем на
директиву, начинаются теперь с буквы P, типа P286N. Все директивы
принудительной генерации состояния ошибки типа .ERRxxx
переименованы и имеют форму ERRIFxxx. Некоторым другим директивам
их прежние имена оставлены, за исключением ведущей точки.

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

————————————————————
Режим MASM Режим Ideal Режим MASM Режим Ideal
————————————————————
.186 P186 .ERR2 ERRIF2
.286 P286N .ERRB ERRIFB
.286C P286N .ERRDEF ERRIFDEF
.286P P286 .ERRDIF ERRIFDIF
.287 P287 .ERRDIFI ERRIFDIFI
.386 P386N .ERRE ERRIFE
.386C P386N .ERRIDN ERRIFIDN
.386P P386 .ERRIDNI ERRIFIDNI
.387 P387 .ERRNB ERRIFNB
.8086 P8086 .ERRNDEF ERRIFNDEF
.8087 P8087 .ERRNZ ERRIF
.CODE CODESEG .FARDATA FARDATA
.CONST CONST .FARDATA? UFARDATA
.DATA DATASEG .MODEL MODEL
.DATA? USEDATASEG .RADIX RADIX
.ERR ERR .STACK STACK
.ERR1 ERRIF1
————————————————————

Обмен местами директивы и символического имени
———————————————-

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

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

———————————————
Режим MASM Режим Ideal
———————————————
имя ENDP ENDP [имя]
имя ENDS ENDS [имя]
имя GROUP сегменты GROUP имя сегменты
имя LABEL тип LABEL имя тип
имя MACRO аргументы MACRO имя аргументы
имя PROC тип PROC имя тип
имя RECORD аргументы RECORD имя аргументы
имя SEGMENT аргументы SEGMENT имя аргументы
имя STRUC STRUC имя
имя UNION UNION имя
———————————————

Отметим, что в директивах ENDS и ENDP, закрывающих
определения, задания имен, совпадающих с именами, заданными при
отктытии определения, не требуется. Если же имя задано, то оно
должно быть записано в точности так же, как и в соответствующей
директиве SEGMENT или PROC. Некоторые программисты для улучшения
читаемости своих программ всегда включают это имя в закрывающую
директиву. Данное свойство особенно полезно в случае вложенных
процедур или сегментов, однако оно не является строго
обязательным.

Некоторые директивы идентичны для обоих режимов, MASM и
Ideal. Например, директивы, приведенные ниже, определяют
символические имена как часть синтаксиса языка и следовательно,
одинаковы в обоих режимах:

= DD DQ
: DF DT
DB DP DW
EQU

Строки символов в кавычках, задаваемые директивам как аргументы
—————————————————————

В режиме Ideal директива INCLUDE принимает имя файла в
кавычках:

INCLUDE «MYDEFS.INC»

В режиме MASM использование кавычек не требуется:

INCLUDE MYDEFS.INC

%TITLE и %SUBTTL также требуют заключения передаваемых им
строк заголовков в кавычки:

%TITLE «Macro Definitions» ;комментарий игнорируется
%SUBTTL «Block Structuring Macros» ;комментарий игнорируется

Как показано в этих двух примерах, тот факт, что заголовки и
подзаголовки заключаются в кавычки, позволяет помещать в конце
строк комментарии. Эти комментарии в файл листинга включены не
будут. В режиме же MASM частью строки заголовка становится все,
что расположено после директив .TITLE и .SUBTTL, включая любые
комментарии.

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

Способ, которым Turbo Assembler работает с сегментами и
группами в режиме Ideal, может вызвать серьезные затруднения с
точки зрения запуска и выполнения программы. Если вы такой же
человек, как и все прочие, то вас должна приводить в трепет одна
мысль о том, что вам придется искать ошибку, связанную с
взаимодействием сегментов и групп.

Большинство из этих сложностей связано с произвольным
способом, которым MASM, и следовательно, Turbo Assembler в режиме
MASM, делает предположения о ссылках к данным или программе в
группе. К счастью, режим Ideal решает часть наиболее неприятных
проблем, связанных с работой сегментных и групповых директив MASM;
это показано в следующей ниже информации.

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

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

Режим MASM работает с этим по-разному: иногда символическое
имя рассматривается как часть сегмента, а не группы. В частности,
режим MASM рассматривает символическое имя как часть сегмента,
когда оно используется с операцией OFFSET, но как часть группы,
когда оно используется в качестве указателя при распределении
данных. Это может вызывать путаницу, поскольку при прямом доступе
к данных без OFFSET MASM ошибочно генерирует ссылку относительно
сегмента вместо группы.

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

dseg1 SEGMENT para public ‘data’
v1 db 0
dseg1 ENDS
dseg2 SEGMENT para public ‘data’
v2 db 0
dseg2 ENDS
dseg3 SEGMENT para public ‘data’
v3 db 0
dseg3 ENDS
DGROUP GROUP dseg1,dseg2,dseg3
cseg SEGMENT para public ‘code’
ASSUME cs:cseg,ds:DGROUP
start:
mov ax,OFFSET v1
mov bx,OFFSET v2
mov cx,OFFSET v3
cseg ENDS
END start

Здесь три сегмента, desg1, dseg2 и dseg3, сгруппированы под
одним именем, DGROUP. в результате все переменные конкретных
сегментов хранятся в памяти вместе. В исходном тексте программы
каждый из отдельных сегментов объявляет байтовую переменную; их
имена v1, v2 и v3.

В кодовой части программы MASM адреса смещения этих трех
переменных загружаются в регистры AX, BX и CX. Вследствие
предыдущей директивы ASSUME и поскольку сегменты данных были
сгруппированы все вместе, вам могло показаться, что MASM будет
вычислять смещения переменных относительно всей группы в целом, в
которой в конечном счете эти переменные находятся в памяти.

Однако все происходит не так. Несмотря на ваши намерения,
MASM вычисляет смещения переменных относительно конкретных
сегментов, dseg1, dseg2 и dseg3. Это происходит несмотря на то,
что три указанных сегмента объединены в памяти в один сегмент,
адресуемый через регистр DS. Брать смещения переменных в тексте
программы относительно конкретных сегментов, когда в памяти они
объединены в один сегмент, не имеет смысла. Единственный способ
адресации таких переменных состоит в том, чтобы ссылаться на их
смещения относительно всей группы в целом.

Для решения данной проблемы в MASM необходимо задавать имя
группы вместе с ключевым словом OFFSET:

mov ax,OFFSET DGROUP:v1
mov bx,OFFSET DGROUP:v2
mov cx,OFFSET DGROUP:v3

Хотя теперь ассемблирование будет выполняться правильно, и
загрузка смещений v1, v2 и v3 будет происходить относительно
DGROUP (где собраны отдельные сегменты), вы легко можете забыть
задать квалификатор DGROUP. Если вы сделаете такую ошибку, то
значения смещения неправильно адресуют переменные в памяти, и вы
не получите от MASM никаких указаний относительно этой ошибки, за
исключением того, что все неправильно. В режиме Ideal об этом
беспокоиться не требуется:

IDEAL
SEGMENT dseg1 para public ‘data’
v1 db 0
ENDS
SEGMENT dseg2 para public ‘data’
v2 db 0
ENDS
SEGMENT dseg3 para public ‘data’
v3 db 0
ENDS
GROUP DGROUP dseg1,dseg2,dseg3
SEGMENT cseg para public ‘code’
ASSUME cs:cseg,ds:DGROUP
start:
mov ax,OFFSET v1
mov bx,OFFSET v2
mov cx,OFFSET v3
ENDS
END start

Смещения v1, v2 и v3 правильно вычисляются относительно
группы, в которую собраны отдельные сегменты, к которым
принадлежат переменные. В режиме Ideal для ссылки к переменным в
сгруппированных сегментов задавать квалификатор DGROUP не
трбуется. В режиме MASM такой квалификатор нужен, и что еще хуже,
в этом режиме не выдается никаких сообщений о серьезных проблемах
в случае, если вы забудете хотя бы в какой-либо одной ссылке
задать имя группы.

Определение ближних или дальних меток кода ——————-

При определении ближних или дальних символических имен LABEL
или PROC ссылки на эти имена выполняются относительно группы,
содержащей сегмент. Если сегмент символического имени не является
частью группы, то данное символическое имя бепется относительно
сегмента. Это означает, что вам не требуется использовать для
сегмента директиву ASSUME CS, чтобы определить ближние или дальние
символические имена. Фрагмент в режиме MASM

CODE SEGMENT
ASSUME CS:CODE
XYZ PROC FAR
.
. ;код процедуры MASM
.
XYZ ENDP
CODE ENDS

в режиме Ideal имеет вид:

SEGMENT CODE
PROC XYZ FAR
.
. ;код процедуры Ideal
.
ENDP
ENDS

Данное изменение не добавляет каких-либо новых возможностей к
тем, что были в режиме MASM. Однако, оно освобождает вас от
необходимости всякий раз сообщать ассемблеру те сведения, которые
в режиме Ideal он может вывести и сам.

Внешние, общие и глобальные символические имена —————

В тех случаях, когда вам необходимо задать тип (BYTE, WORD и
т.д.), например, в директивах EXTRN или GLOBAL, вы можете
использовать имя структуры:

STRUC MoreStuff
HisStuff DB 0
HerStuff DW 0
ItsStuff DB 0
ENDS
EXTRN SNAME:MoreStuff

Данное средство, в сочетании с улучшенными возможностями
операции точка (.), описанной ранее, позволяют вам делать ссылки
на члены структур, являющиеся внешними относительно вашего
исходного модуля. Дело обстоит так, как если бы вы объявили эти
члены внутри обоих модулей. Операция SIZE также правильно сообщает
о размере внешних структур данных. Каждое символическое имя типа
PUBLIC, выданное в режиме Ideal, помещается там же, где задается
PUBLIC. Это полезно с точки зрения переопределения переменных. В
режиме MASM все общие символические имена выдаются в конце
программы, тем самым ограничивая способы переопределения общих
символических имен. Например,

Perfect = 8
PUBLIC Perfect ;Perfect объявляется как PUBLIC
Perfect = 10 ;переопределение значения Perfect

В режиме MASM PUBLIC Perfect равно 8, даже если в модуле
Perfect после объявления его PUBLIC переопределяется. В режиме
Ideal, поскольку символические имена PUBLIC выданы в конце модуля,
другой модуль, принимающий данное символическое имя через
объявление EXTRN, принимает Perfect со значением 10.

Прочие различия ————————————————

В данном разделе описано несколько дополнительных различий
между режимами MASM и Ideal.

Подавленные фиксации
———————

В режиме Ideal Turbo Assembler не генерирует сегментных
фиксаций для сегментов типа PRIVATE, выравненных по границе
страницы или параграфа. Поскольку компоновщику такие фиксации не
требуются, ассемблирование программ в режиме Ideal может дать
меньшие по размеру объектные файлы, которые также быстрее
компонуются, чем объектные файлы, генерируемые в режиме MASM.
Следующий пример демонстрирует, как в режиме MASM образуются
излишние фиксации, в отличие от режима MASM:

SEGMENT DATA PRIVATE PARA
VAR1 DB 0
VAR2 DW 0
ENDS
SEGMENT CODE
ASSUME ds:DATA
mov ax,VAR2 ;фиксация не требуется
ENDS

Данное различие не влияет на создаваемые вами программы.
Информация о нем приводится просто для вашего сведения.

Операнд команды BOUND
———————

Команда BOUND ожидает прием операнда типа WORD, а не DWORD.
Это позволяет вам определить нижнюю и верхнюю границы в виде двух
слов-констант, отменяя необходимость в преобразовании операнда к
типу DWORD явным заданием DWORD PTR. В режиме MASM вы должны
записать

BOUNDS DW 1,4 ;нижняя и верхняя границы
BOUND DWORD PTR BOUNDS ;требуется только в режиме MASM

в режиме же Ideal нужно записать просто

BOUNDS DW 1,4 ;нижняя и верхняя границы
BOUND [BOUNDS] ;допустимо только в режиме Ideal

Комментарии в макросах
———————-

В режиме Ideal комментарии в макросах обрабатываются, как
строки символов. Для подстановки в комментарий значения фиктивного
параметра нужно поместить перед ним знак амперсенд (&):

MACRO DOUBLE ARG
SHL arg,1 ;умножить &ARG на два
ENDM

При использовании данного макроса в режиме Ideal с DOUBLE BX
файл листинга покажет:

SHL bx,1 ;умножить BX на два

С другой стороны, если макрос определен как

MACRO DOUBLE arg
SHL arg,1 ;умножить ARG на два
ENDM

то в файле листинга ARG заменен не будет:

SHL bx,1 ;умножить ARG на два

Локальные символические имена
——————————

При переключении в режим Ideal средство локальных
символических имен Turbo Assembler включается автоматически, как
если бы вы ввели директиву LOCALS.

Сравнение программирования в режимах MASM и Ideal
——————————————————————

В завершение данной главы для того, чтобы вы почувствовали
различия между режимами Ideal и MASM, приводится пример одной и
той же программы для двух режимов. Ideal и MASM. Прочитав
приведенные программы и изучив после листинга пронумерованные
комментарии, вы вполне сможете оценить преимущества,
предоставляемые синтаксисом режима Ideal.

Пожалуйста, учтите, что эти программы не служат для
демонстрации хорошего стиля программирования: содержащиеся в них
команды просто демонстрируют концепции режима Ideal, обсуждавшиеся
в этой главе, и дают понятие о наиболее общих возможностях режима
Ideal и его отличиях от режима MASM.

Данные программы считывают с консоли одну строку,
преобразовывают буквы текста к верхнему регистру и перед возвратом
в DOS выводят результат на дисплей. Для того, чтобы отметить те
места, в которых коды программ в режимах MASM и ideal отличны друг
от друга, добавлен комментарий (начинайщийся с точки с запятой),
представляющий собой число. Например, ;4 говорит о том, что вы
должны прочесть пункт 4 в следующем после листинга разделе «Анализ
режимов MASM и Ideal» . Кроме того, для того, чтобы сделать
особенно заметными те места листинга для режима Ideal, где имеются
указанные различия, все прочие комментарии мы оттуда удалили.
Прочитайте первую программу, чтобы понять, как составляющие ее
коды работают. Прочитайте вторую программу, чтобы сравнить ее с
первой с точки зрения улучшений, вносимых режимом Ideal.

Пример программы для режима MASM
———————————

; Файл
; Пример программы для режима MASM, преобразующей буквы вве-
; денной строки к верхнему регистру.
TITLE Example MASM Program ;комментарий входит в заголовок!
.286
bufsize = 128 ;размер буферов ввода и вывода
dosint MACRO intnum
mov ah,intnum ;присвоить AH номер функции
int 21h ;вызов функции DOS номер &INTNUM
ENDM
stk SEGMENT STACK
db 100h DUP (?) ;резервирование области стека
stk ENDS
data SEGMENT WORD
inbuf db bufsize DUP (?) ;буфер ввода
outbuf db bufsize DUP (?) ;буфер вывода
data ENDS
DGROUP GROUP stk,data ;группировка сегментов стека и
;данных
code SEGMENT WORD
ASSUME cs:code ;назначить на CS кодовый сегмент
start:
mov ax,DGROUP ;присвоить адрес сегмента
mov ds,ax ;DGROUP в DS
ASSUME ds:DGROUP ;сегмент данных по умолчанию DS
mov dx,OFFSET DGROUP:inbuf ;загрузка смещения inbuf в DX
xor bx,bx ;стандартное устройство ввода
call readline ;чтение одной строки
mov bx,ax ;присвоить длину BX
mov inbuf[bx],0 ;добавить заканчивающий строку 0
push ax ;запомнить AX в стеке
call mungline ;преобразовать строку к верхнему
;регистру
pop cx ;восстановить счетчик
mov dx,OFFSET DGROUP:outbuf ;загрузка смещения outbuf в DX
mov bx,1 ;стандартное устройство вывода
dosint 40h ;функция записи в файл
dosint 4ch ;функция возврата в DOS

; Чтение строки, вызов при dx => буфер, возвращает счетчик в AX
readline PROC near
mov cx,bufsize ;задание размера буфера
dosint 3fh ;функция чтения файла
and ax,ax ;установка флага нуля счетчика
ret ;возврат к вызывающей программе
readline ENDP

; Преобразование букв строки к верхнему регистру
mungline PROC NEAR
mov si,OFFSET DGROUP:inbuf ;адресация inbuf при помощи SI
mov di,0 ;инициализация DI
@@uloop:
cmp BYTE PTR[si],0 ;конец текста?
je @@done ;если да, то переход к @@done
mov al,[si] ;иначе прием следующего символа
and al,not ‘a’ — ‘A’ ;преобразование к верхнему
;регистру
mov outbuf[di],al ;запись в буфер вывода
inc si ;лучше использовать lodsb, stosb
inc di ;… это просто пример!
jmp @@uloop ;продолжаем преобразование текста
@@done: ret
mungline ENDP ;конец процедуры

code ENDS ;конец кодового сегмента
END start ;конец текста и точка входа в DOS

Пример программы для режима Ideal
———————————

; Файл
; Пример программы для режима Ideal, преобразующей буквы вве-
; денной строки к верхнему регистру.
IDEAL ;1
%TITLE «Example Ideal-Mode Program ;2
P286N ;3
bufsize = 128
MACRO dosint intnum ;4
mov ah,intnum
int 21h
ENDM
SEGMENT stk STACK ;5
db 100h DUP (?)
ENDS ;6
SEGMENT DATA WORD ;7
inbuf db bufsize DUP (?)
outbuf db bufsize DUP (?)
ENDS DATA
GROUP DGROUP stk,DATA ;9
SEGMENT CODE WORD ;10
ASSUME cs:code
start:
mov ax,DGROUP
mov ds,ax
ASSUME ds:DGROUP
mov dx,OFFSET inbuf ;11
xor bx,bx
call readline
mov bx,ax
mov [inbuf + bx],0 ;12
push ax
call mungline
pop cx
mov dx,OFFSET outbuf ;13
mov bx,1
dosint 40h
dosint 4ch

; Чтение строки, вызов при dx => буфер, возвращает счетчик в AX
PROC readline near ;14
mov cx,bufsize
dosint 3fh
and ax,ax
ret
ENDP ;15

; Преобразование букв строки к верхнему регистру
PROC mungline NEAR ;16
mov si,OFFSET inbuf ;17
mov di,0
@@uloop:
cmp [BYTE si],0 ;18
je @@done
mov al,[si]
and al,not ‘a’ — ‘A’
mov [outbuf + di],al ;19
inc si
inc di
LODSB/STOSB
jmp @@uloop
@@done: ret
ENDP mungline ;20
ENDS ;21
END start

Анализ режимов NASM и Ideal ———————————

В следующих параграфах подробно раскрываются различия между
конструкциями, директивами и операндами режимов MASM и Ideal по
двум предыдущим примерам программ. Номер каждого параграфа
соответствует номеру комментария в примере для режима Ideal.
Сравните эти строки с соответствующими строками программы для
режима MASM.

1. Для переключения в режим Ideal служит директива IDEAL. По
умолчанию Turbo Assembler всегда начинает ассемблирование
исходного файла в режиме MASM. Директиву MASM требуется ис-
пользовать только в тех случаях, когда необходимо вернуться
обратно к режиму MASM после ранее выполненного переключения
в режим Ideal.

2. Знак процента перед директивой %TITLE напоминает вам о том,
что данная директива влияет на файл листинга (если вы ре-
шили создать таковой, либо задав его имя, либо задав опцию
командной строки /L при запуске ассемблирования.) В режиме
Ideal используется форма %TITLE вместо TITLE (без знака
процента), и кроме того, требуется заключать строку заголовка
в кавычки (» «). Это позволяет поместить в данную строку
комментарий, в отличие от режима MASM, где этот комментарий
стал бы частью заголовка, что скорее всего не отвечало бы
вашим намерениям.

3. Директиве .286 режима MASM соответствует директива P286N
режима Ideal. Поскольку в режиме Ideal символические имена
не могут начинаться с точки (.), все директивы управления
и прочие начинающиеся с точки директивы режима MASM изме-
нены. Данный оператор в листинге не выполняет никаких по-
лезных задач, за исключением демонстрации различия его за-
писи в этих двух режимах. Дело в том, что в данной прог-
рамме каких-либо специфических команд 80286 не используется.

4. В режиме Ideal имя макроса следует после директивы MACRO,
а не до нее, как в режиме MASM.

5. В режиме Ideal имя сегмента находится после директивы
SEGMENT.

6. При использовании директивы ENDS, закрывающей сегмент, в
режиме Ideal помещать в этой же строке соответствующее имя
сегмента, как в режиме MASM, не обязательно. (Однако при
желании можно указать это имя после директивы ENDS.)

7. То же, что в параграфе 5. И опять ключевое слово SEGMENT
помещается перед именем.

8. Если вы указали в директиве ENDS соответствующее имя сег-
мента, то это имя должно стоять после директивы, а не до
нее, как это было в режиме MASM. При желании это имя (в
данном случае DATA) можно удалить из строки.

9. В режиме Ideal директива GROUP предшествует имени группы
сегментов данных (DGROUP). После следует список сегментов
данных, которые вы хотите сгруппировать под этим именем.
В режиме MASM GROUP и имя помещаются в обратном порядке.

10.То же, что в параграфе 5. Ключевое слово SEGMENT предшес-
твует имени.

11.Использовать в этом месте с операцией OFFSET квалификатор
группы не требуется. Режим Ideal предполагает, что INBUF
адресуется относительно начала DGROUP, поскольку INBUF
находится внутри одного из отдельных сегментов, собранных
в группу с этим именем. В режиме MASM для правильного за-
дания смещений переменных в сгруппированных сегментах вы
должны не забыть задать квалификатор типа DGROUP:inbuf.

12.Операнд [INBUF+BX] допустим как в режиме Ideal, так и в
режиме MASM, однако та же строка в форме INBUF[BX], при-
емлемой для режима MASM, в режиме Ideal недопустима.
В режиме Ideal все операнды, адресующие память, должны
быть взяты в квадратные скобки.

13.То же, что в параграфе 11. И снова, не требуется задавать
имя группы для ссылки на переменную в сгруппированном сег-
менте. В режиме MASM для получения правильного смещения
OUTBUF вы должны записать DGROUP:outbuf. Если в режиме MASM
забыть указать квалификатор DGROUP, то в данном случае вы-
ход будет помещен не туда, куда вы ожидали, а в стек, причем
MASM никаких сообщений о случившейся серьезной ошибки выдать
не сможет!

14.Имя процедуты следует после директивы PROC, а не до нее,
как требовалось в режиме MASM.

15.При использовании директивы ENDP, закрывающей процедуру, в
режиме Ideal помещать в этой же строке соответствующее имя
процедуры, как в режиме MASM, не обязательно.

16.То же, что в параграфе 14. Директива PROC предшествует имени
процедуры.

17.То же, что в параграфе 11. И снова, записывать DGROUP:inbuf,
как это было в режиме MASM, не нужно.

18.В режиме Ideal операция PTR при установке размера выражения
может быть при желании опущено. Выражение BYTE PTR ABC ре-
жима MASM идентично выражению BYTE ABC режима Ideal.

19.То же, что в параграфе 12. В режиме Ideal при ссылке на со-
держимое памяти выражение, адресующее память, всегда должно
заключаться в квадратные скобки.

20.При желании после директивы ENDP можно поместить соответст-
вующее имя процедуры, в отличие от режима MASM, где имя про-
цедуры должно стоять перед этой директивой.

21.То же, что в параграфе 6. Директива ENDS не требует задания
соответствующего имени сегмента, хотя при желании оно может
быть задано.

Загрузка...