Что такое общее имя в ассемблере

EXTRN и PUBLIC

Редактор связей не может, однако, выполнить все, о чем говорилось
выше, самостоятельно. Ассемблер должен получить от программиста
информацию о подпрограммах, относящихся к другому программному
модулю. Это ввполняется с помощью оператора PUBLIC, извещающего
ассемблер о том, что данное символическое имя доступно другим
программам. Кроме того, программист указывает ассмеблеру, какие из
символических имен является внешними для данного программного
модуля. В языке ассемблера это реализуется оператором EXTRN,
который объявляет соответствующее имя внешним для текущего
ассемблирования, чтобы оно могло быть правильно обработано.
Ассемблер помечает данную команду таким образом, чтобы редактор
связей мог впоследствии найти ее и вставить туда правильное
значение адреса.

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

Вторая функция оператора EXTRN состоит в том, что он указывает
ассемблеру тип соответствующего символического имени. Так как
ассемблирование является очень формальной процедурой, то ассемблер
должен знать, что представляет из себя каждый символ. Это позволяет
ему генерировать правильные команды. В случае данных оператор EXTRN
может указывать на байт, двойное слово или другой типовой элемент.
Тип имени подпрограммы или другой программной метки может быть либо
NEAR, либо FAR, в зависимости от того, в каком сегменте она
находится. От программиста требуется указать в операторе EXTRN тип
символического имени. Так как кроме того ассемблером осуществляется
посегментная адресация программы, то оператор EXTERN указывает на
сегмент, в котором появляется данный идентификатор. Это не входит в
синтаксис оператора EXTRN, а определяется местоположением этого
оператора в программе. Ассемблер считает, что внешнее имя относится
к тому же сегменту, в котором появляется оператор EXTERN для этого
символического имени.

На Фиг. 5.13 приведен пример ассемблерной программы,
иллюстрирующей использование оператора EXTRN. Здесь имеются два
имени, являющиеся внешними для данной программы. OUTPUT_CHARACTER
обозначает однобайтовую переменную. Соответствующий этой переменной
атрибут «:BYTE» указывается после имени переменной. Указатель NEAR
программной метки OUTPUT_ROUTINE говорит о том, что она находится в
том же сегменте. Хотя приведенная на Фиг. 5.13 прогграмма содержит
ссылки на эти символические имена, при трансляции ассемблер знает,
как ему сегментировать правильные команды. Если бы оператор EXTRN
отсутствовал в программе, то в этом случае ассемблер
инициализировал бы ошибки. Из ассемблерного листинга видно, что
после поля адреса в командах, ссылающихся на внешние имена, стоит
символ E.

Источник

Что такое общее имя в ассемблере

Справочная система по языку Assembler

Структура программы на ассемблере


Синтаксис ассемблера

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 1. Формат предложения ассемблера

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 2. Формат директив

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 3. Формат команд и макрокоманд

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

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

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 4. Синтаксис описания адресных операндов

Результатом вычисления выражения может быть адрес некоторой ячейки памяти или некоторое константное (абсолютное) значение.

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 7. Синтаксис операторов сравнения

Таблица 1. Операторы сравнения

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 9. Синтаксис индексного оператора

Заметим, что в литературе по ассемблеру принято следующее обозначение: когда в тексте речь идет о содержимом регистра, то его название берут в круглые скобки. Мы также будем придерживаться этого обозначения.
К примеру, в нашем случае запись в комментариях последнего фрагмента программы mas + (si) означает вычисление следующего выражения: значение смещения символического имени mas плюс содержимое регистра si.

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 13. Синтаксис оператора получения смещения

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

Таблица 2. Операторы и их приоритет

Директивы сегментации

Синтаксическое описание сегмента на ассемблере представляет собой конструкцию, изображенную на рис. 14:

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 14. Синтаксис описания сегмента

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 15. Директива ASSUME

На уроке 3 мы рассматривали пример программы с директивами сегментации. Эти директивы изначально использовались для оформления программы в трансляторах MASM и TASM. Поэтому их называют стандартными директивами сегментации.

В листинге 1 приведен пример программы с использованием упрощенных директив сегментации:
Синтаксис директивы MODEL показан на рис. 16.

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Рис. 16. Синтаксис директивы MODEL

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

Таблица 3. Упрощенные директивы определения сегмента

Формат директивы
(режим MASM)
Формат директивы
(режим IDEAL)
Назначение
.CODE [имя]CODESEG[имя]Начало или продолжение сегмента кода
.DATADATASEGНачало или продолжение сегмента инициализированных данных. Также используется для определения данных типа near
.CONSTCONSTНачало или продолжение сегмента постоянных данных (констант) модуля
.DATA?UDATASEGНачало или продолжение сегмента неинициализированных данных. Также используется для определения данных типа near
.STACK [размер]STACK [размер]Начало или продолжение сегмента стека модуля. Параметр [размер] задает размер стека
.FARDATA [имя]FARDATA [имя]Начало или продолжение сегмента инициализированных данных типа far
.FARDATA? [имя]UFARDATA [имя]Начало или продолжение сегмента неинициализированных данных типа far
Наличие в некоторых директивах параметра [имя] говорит о том, что возможно определение нескольких сегментов этого типа. С другой стороны, наличие нескольких видов сегментов данных обусловлено требованием обеспечить совместимость с некоторыми компиляторами языков высокого уровня, которые создают разные сегменты данных для инициализированных и неинициализированных данных, а также констант.

При использовании директивы MODEL транслятор делает доступными несколько идентификаторов, к которым можно обращаться во время работы программы, с тем, чтобы получить информацию о тех или иных характеристиках данной модели памяти (см. табл. 5). Перечислим эти идентификаторы и их значения (табл. 4).

Таблица 4. Идентификаторы, создаваемые директивой MODEL

Имя идентификатораЗначение переменной
@codeФизический адрес сегмента кода
@dataФизический адрес сегмента данных типа near
@fardataФизический адрес сегмента данных типа far
@fardata?Физический адрес сегмента неинициализированных данных типа far
@cursegФизический адрес сегмента неинициализированных данных типа far
@stackФизический адрес сегмента стека
Если вы посмотрите на текст листинга 1, то увидите пример использования одного из этих идентификаторов. Это @data ; с его помощью мы получили значение физического адреса сегмента данных нашей программы.

Таблица 5. Модели памяти

Таблица 6. Модификаторы модели памяти

Значение модификатораНазначение
use16Сегменты выбранной модели используются как 16-битные (если соответствующей директивой указан процессор i80386 или i80486)
use32Сегменты выбранной модели используются как 32-битные (если соответствующей директивой указан процессор i80386 или i80486)
dosПрограмма будет работать в MS-DOS
Необязательные параметры язык и модификатор языка определяют некоторые особенности вызова процедур. Необходимость в использовании этих параметров появляется при написании и связывании программ на различных языках программирования.

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

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

Источник

Основные директивы IBM PC


Глава из книги “Искусство программирования на Ассемблере”


Автор: Н. Голубь
Источник: Искусство программирования на Ассемблере
Материал предоставил: Издательство «Питер»

Опубликовано: 24.06.2006
Версия текста: 1.0

Преимущества и недостатки изучения языка Ассемблера с использованием известных алгоритмических языков Pascal и C/C++

Язык Ассемблера можно изучать по-разному. Можно начинать изучать язык сам по себе, а за результатами следить через отладчик — это обычный, классический путь (см. п. 5.1.1.3).

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

Именно по этому пути мы и пойдем с самого начала (см. п. 5.1.1.2). Таким образом, различные тонкости языка Ассемблера будут раскрываться постепенно, по мере усвоения материала и появления опыта, а значит, и уверенности в своих силах.

Разница между директивами и командами Ассемблера

Имя в Ассемблере может начинаться с любого допустимого символа, кроме цифры. Если имя содержит символ точки ‘.’, то он должен быть ПЕРВЫМ символом. Имя НЕ может быть зарезервированным в Ассемблере словом (имя машинной команды или директивы).

С некоторыми директивами мы с вами уже успели и поработать — см. примеры 2.9 и 2.10.

Команда Ассемблера всегда генерирует машинный код.

Директивы имеют разный синтаксис в режимах MASM (поддерживается компиляторами Microsoft Assembler — masm и Borland (Turbo) Assembler — tasm ) и Ideal (поддерживается компилятором tasm ) — см. приложение 5.

При описании синтаксиса директив и команд обычно используют специальный язык, известный всем профессиональным программистам, — язык Бэкуса-Наура (названный так в честь этих двух достойных ученых). Мы будем использовать его упрощенный вариант:

Директив достаточно много. Практически каждая версия компилятора что-то из директив добавляет или немного изменяет синтаксис. Для определенности мы в данной главе остановимся на синтаксисе основных директив в более универсальном формате MASM для компиляторов masm-6.12 (или выше) и tasm-3.1 (или выше). Кроме того, известные компиляторы с языка программирования С/С++ ( Borland C++, Visual C++ ) выдают ассемблерный листинг именно в формате MASM. И очень скоро мы научимся его читать…

Описание сегмента — директива SEGMENT

Из п. 2.4.3 мы знаем, что любые ассемблерные программы содержат, по крайней мере, один сегмент — сегмент кода. В некоторых программах используется сегмент для стековой памяти и сегмент данных (основной и дополнительный) для определения данных.

Имя сегмента ( имяС ) должно обязательно присутствовать, быть уникальным и соответствовать соглашениям для имен в Ассемблере или в другом алгоритмическом языке, для стыковки с которым делается ассемблерный модуль. Например, при стыковке Ассемблера с Turbo/Borland Pascal имяС должно быть СТРОГО определенным:

В одном модуле можно открывать и закрывать сегмент с одним и тем же именем имяС несколько раз, но пересекаться (вкладываться друг в друга) разные сегменты НЕ должны. Компилятор просматривает ассемблерный модуль и объединяет вместе все части сегментов с одинаковым именем в том порядке, в каком он их обнаруживает (сверху-вниз).

Директива SEGMENT может содержать три основных типа необязательных параметров, определяющих выравнивание ( align ), объединение ( combine ) и класс (‘ class’ ), между которыми должен быть хотя бы один пробел в качестве разделителя. Параметры имеют смысл при разработке БОЛЬШИХ ассемблерных программ.

ПараметрЗначение
BYTEВыравнивание НЕ выполняется. Сегмент размещается, начиная со следующего байта.
WORDНачало сегмента выравнивается на границу слова (четный адрес, кратный 2)
DWORDНачало сегмента выравнивается на границу двойного слова (четный адрес, кратный 4)
PARAНачало сегмента выравнивается на границу параграфа (четный адрес, кратный 16, см.п.3.4.3). Это значение принято по умолчанию.
PAGEНачало сегмента выравнивается на границу страницы (четный адрес, кратный 256)
MEMPAGEНачало сегмента выравнивается на границу страницы памяти (четный адрес, кратный 4K)
Таблица 4.1. Параметр выравнивания (align)

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

Эта директива используется для объединения сегментов в группу. Она имеет следующий формат:

Группа позволяет осуществлять доступ к данным из всех сегментов, которые находятся в ней, с помощью одной загрузки адреса группы в сегментный регистр. Этим широко пользуются компиляторы С/С++.

Директива Assume

В качестве сегментных регистров для базового Ассемблера принимаются уже известные нам регистры: CS, DS, ES или SS.

Для ОТМЕНЫ назначения для данного сегментного регистра используется ДРУГОЙ формат этой директивы:

Чаще всего эта директива используется в начале модуля на Ассемблере.

Рассмотрим фрагмент листинга ассемблерного файла, который был получен компилятором Borland C++ 5.02 :

Ну, как? Все понятно? Вот мы и начинаем немного понимать, что же делают компиляторы с алгоритмических языков…

Стандартные модели памяти


Директива MODEL

Директива MODEL позволяет задавать в ассемблерной программе одну из нескольких стандартных моделей сегментации памяти ( модель_памяти) — см. табл. 3.3. Приведем ее упрощенный формат, которым мы будем пользоваться в дальнейшем:

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

Определившись с используемой моделью, можно использовать упрощенные директивы описания основных сегментов (регистр букв НЕСУЩЕСТВЕНЕН!):

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

Модуль на Ассемблере, как и модули на алгоритмических языках, обычно состоит из процедур. Для описания процедур используются две директивы. Визуально они похожи на соответствующие директивы описания сегмента — см. п. 4.2:

Описание внешних ссылок

Как было заявлено в п. 4.1, мы будем использовать алгоритмические языки Pascal и C/C++ в качестве помощников при изучении Ассемблера. Таким образом, сразу начинаем работать с РАЗНЫМИ модулями, да еще и на разных языках! Поэтому нам не миновать ВНЕШНИХ ссылок. Что это такое? Это — использование в одном модуле имен, описанных в других модулях.

Директива описания общих имен PUBLIC

Эта директива указывает компилятору и компоновщику, что данное имя (его адрес) должно быть доступно для других программ. Имена могут быть метками, переменными или именами подпрограмм.

Например, если мы хотим использовать в языке С/С++ функцию с именем Prim, реализованную в Ассемблере, то она в ассемблерном модуле должна быть описана следующим образом:

Директива описания внешних имен EXTRN

Например, в модуле на алгоритмическом языке Pascal ( Borland/Turbo Pascal-5.5/6.0/7.0х ) мы описали следующие глобальные переменные:

А использовать их собираемся в ассемблерном модуле. В этом случае директива будет иметь вид:

Язык Pascal НЕ различает регистр букв в именах. А директива EXTRN содержит только ОДНУ гласную букву — начинающие программисты часто на этом спотыкаются… Будьте ВНИМАТЕЛЬНЫ!

Вопросы

Если вы правильно ответили на ВСЕ вопросы, значит, вы ХОРОШО УСВОИЛИ главу 2 (п. 2.2) — поздравляю. Если НЕТ, не беда — все у вас еще впереди (просто пока маловато опыта).

Источник

Что такое общее имя в ассемблере

Большая часть данной главы будет носить справочный характер. Почему я привожу справочный материал в середине книги, а не в ее начале? Просто я убежден, что справка в начале книги может отбить всякую охоту читать дальше. Многое из того, что я привожу в данной главе. Вы уже знаете и, следовательно, Вам интересно будет читать материал этой главы.

1. Метка с двоеточием после имени определяет адрес следующей за меткой команды.

2. Директива LABEL позволяет определить явно тип метки. Значение же определенной таким образом метки равно адресу команды или данных, стоящих далее. Например,
LABEL L1 DWORD.

3. Выражение ИМЯ PROC определяет метку, переход на которую обычно происходит по команде CALL. Блок кода, начинающийся с такой метки, называют процедурой. Впрочем, переход на такую метку можно осуществлять и с помощью JMP, как, впрочем, и команду CALL можно использовать для перехода на обычную метку. В этом, несомненно, состоит сила и гибкость ассемблера.

6. Метка «$» всегда определяет текущий адрес.

7. В MASM метки, стоящие в процедуре, автоматически считаются локальными и, следовательно, имена меток в процедурах могут дублироваться. В TASM все метки по умолчанию считаются глобальными. Чтобы сделать метки, стоящие в процедуре локальными, они должны иметь префикс @@, а в начале программы следует указать директиву LOCALS (см. предыдущую главу).

1. Директива STRUC позволяет объединить несколько разнородных данных в одно целое. Эти данные называются полями. Вначале при помощи STRUC определяется шаблон структуры, затем с помощью директивы можно определить любое количество структур. Рассмотрим пример:

Доступ к полям структуры осуществляется посредством точки: COMP1.RE.

2. Объединение. Объединение определяется при помощи ключевого слова UNION. От структуры объединение отличается только тем, что все поля располагаются в структуре с нулевым смещением, т.е. накладываются друг на друга.

1. Условное ассемблирование дает возможность при трансляции обходить тот или иной участок программы. Существует три вида условного ассемблирования.
Условие считается не выполненным, если выражение принимает значение 0 и выполненным, если выражение отлично от нуля.

2. Ассемблеры MASM и TASM поддерживают также несколько условных специальных директив, назовем некоторые из них.

б) Операторы IF1 и IF2 проверяют первый и второй проход при ассемблировании.

Условное ассемблирование понадобится нам в конце главы для написания программы, транслируемой как в MASM, так и TASM.

1. Повторение, заданное опеделенное число раз. Используется макродиректива REPT. Например:
Будет сгенерировано 100 директив DB 10. С этой директивой удобно использовать оператор «=», который позволяет изменять значение переменной многократно, т.е. использовать выражение типа А = А + 5.

2. Директива IRP.
Блок будет вызываться столько раз, сколько параметров в списке. Например:
Приведет к генерации следующих строк:

Пример:
Данный фрагмент эквивалентен следующей последовательности:

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

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

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

1. Кроме объявлений с использованием директив PUBLIC и EXTERN, возможно объявление при помощи директивы GLOBAL, которая действует, как PUBLIC и EXTERN одновременно.

38 В операционной системе MS DOS это было существенно.

1. Условные конструкции.

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

На Рис. 2.6.1 представлена программа, транслируемая и в MASM, и TASM. Программа весьма проста, но рассмотрения ее вполне достаточно для создания более сложных подобных совместимых программ.

Источник

Символические имена в языке ассемблера

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

позволяет затем написать

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

Для резервирования памяти и установления связи между переменными и машинными адресами выделенных для них областей памяти используются псевдокоманды DS и DC. С помощью псевдокоманд EQU константам присваиваются имена.

Команда DS

Когда мы составляем программу для обработки некоторой информации, хранящейся в памяти, то нам нужно позаботиться о резервировании места для этой информации. Одним из способов резервирования памяти является использование команды DS (Define Storage — определить память).

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

В качестве примера рассмотрим предложение

Символ DS располагается в поле операции. Это предложение запрашивает резервирование трех полных слов (3F) и присвоение имени WORDS адресу первого из зарезервированных 12 байтов. Поскольку выделение памяти мы запросили полными словами, будет произведено выравнивание по границе полного слова, т.е. в качестве адреса WORDS будет выбрано значение, кратное 4.

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

Некоторое количество памяти может быть пропущено ассемблером для осуществления выравнивания. Ассемблирование первых двух предложений даст результат

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

18381А46Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере12 байтов зарезервировано Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере1С26

Если следующий после команды AR байт не является байтом полного слова, то для выравнивания будут пропущены 2 байта:

18381А46 Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере2 байта пропущено Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере12 байтов зарезервировано Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере1С26

В рассмотренном примере для иллюстрации принципа выполнения команды DS ассемблером она была помещена между некоторыми машинными командами. Но при выполнении написанной программы машина будет интерпретировать то, что внесено в поле WORDS, как команды со всеми вытекающими отсюда последствиями. Поэтому никогда не следует резервировать память там, где информация, записанная в ней, может быть воспринята как часть выполняемой программы. К вопросу о том, куда же на самом деле следует помещать команды DS и DC, мы вернемся позднее.

Общей формой DS-предложения является

Поле имени может содержать любое имя, допустимое в языке ассемблера, а также может быть оставлено пустым. Сокращение «Кол» (количество) означает коэффициент повторения, т. е. число единиц памяти определенного типа, которое должно быть зарезервировано. Значения в поле «Тип» могу? быть следующими:

Результатом выполнения команды DS будет:

1. Резервирование стольких единиц памяти типа, указанного в поле «Тип», сколько задано полем «Кол» с выравниванием границ, если это необходимо.

2. Присвоение символического имени, указанного в поле имени

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

резервирует пять полуслов и присваивает имя HALVES первому зарезервированному байту. Аналогично предложение

резервирует одно двойное слово (единица, соответствующая значению поля «Кол», может быть опущена), которое получает имя DOUBLE.

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

Команда DC

Команда DC (Define Constant — Определить константу) работает так же, как и DS, но в отличие от нее позволяет производить загрузку начального значения в резервируемую область непосредственно при резервировании. Таким образом, к началу выполнения программы память, заказанная по командеDC, содержит вполне определенную информацию, тогда как никогда нельзя с уверенностью сказать, что содержит сегмент памяти после выполнения команды DS.

Предложение DC имеет формат

Имя DC КолТип’Значение’

«Кол» и «Тип» имеют тот же самый смысл, что и для команды DS. Пока для указания типа будем использовать только

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

В случае использования типов F, D или Н значением может являться любое десятичное число. Перед выполнением программы это число переводится в двоичную форму и записывается на зарезервированное место. Указание десятичных чисел в качестве «значений» является еще одним подтверждением правила: если система счисления не указана явно, все числа в программе на языке ассемблера рассматриваются как десятичные.

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

1. Производится резервирование «Кол» единиц памяти типа «Тип», возможно, с выравниванием границ.

2. Символическое имя, указанное в поле имени, присваивается адресу первого байта зарезервированной области.

3. «Значение» в двоичной форме заносится в эту область памяти.

Отметим, что это значение должно быть заключено в апострофы.

Рассмотрим, например, к чему приведет выполнение предложения

Именем в данном случае является ONE, количество повторений равно 1 (так же как и в случае DS-предложения, единицу можно было опустить), тип — F, а значением является 1. Включение в программу указанного предложения приведет к резервированию выровненного полного слова, присвоению имениONE адресу первого из зарезервированных байтов и записи на выделенное место значения 00000001.

Рассмотрим другой пример,

Здесь резервируется место для трех полуслов, и в каждое из них записывается — 2 в двоичной форме, т. е. FFFE. Имя HALF будет идентифицировать адрес первого байта первого полуслова.

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

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

Наконец, предположим, что мы хотим зарезервировать двойное слово, снабдив его именем DUB, и поместить в него 10010. Необходимый результат получится, если мы внесем в программу предложение

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

Куда же следует помещать предложения DC и DS?

Большая часть обрабатываемых программой данных не является машинными командами. В одном из предыдущих примеров команда DC была помещена в середину программы и был задан вопрос, как пойдет выполнение этой программы в данном случае. Ответ таков: команды AR и LR будут выполнены нормально, затем машина попытается выполнить «команду» с именем HALF. Содержимое первого полуслова (FFFE) будет рассматриваться как команда, а значит, кодом операции является FF. Операции с таким кодом не существует, поэтому выполнение программы будет прервано и будет отмечен особый случай, вызванный недействительным кодом операции. Это означает, что была произведена попытка выполнения несуществующей команды.

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

Что такое общее имя в ассемблере. Смотреть фото Что такое общее имя в ассемблере. Смотреть картинку Что такое общее имя в ассемблере. Картинка про Что такое общее имя в ассемблере. Фото Что такое общее имя в ассемблере

Если нет особой необходимости делать это иначе, размещайте данные после последней реально выполняемой машинной команды в программе. Для нас это означает пока, что предложения DS и DC желательно помещать между последним предложением EOJ и предложением END программы.

Предложение EQU

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

Первое предложение присваивает имени REGSIX числовое значение 6, второе — имени R7 значение 7. Если приведенные предложения будут включены в программу, содержащую команду

то ее выполнение будет эквивалентно выполнению команды

Символические имена в поле операндов просто заменены соответствующими значениями.

Рассмотрим теперь другой пример:

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

Третье предложение демонстрирует еще одну возможность использования символических имен для идентификации адресов. А идентифицирует первый байт области, зарезервированной DS-предложением. Интуитивно ясно, что обозначает А+8: адрес, равный А+8, или байт, отстоящий от байта А на 8. Последнее предложение, следовательно, указывает, что имя С теперь присвоено третьему полному слову поля А.

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

Общие правила составления и записи выражений можно найти в соответствующем руководстве по ассемблеру.

Наконец, рассмотрим результат выполнения пары команд

Символ * в поле операндов предложения языка ассемблера является ссылкой на текущее значение счетчика размещения. В данном случае, поскольку предложение EQU не вызывает генерации машинных кодов, текущим значением счетчика размещения является адрес первого байта команды RWD.Выполнение указанной пары команд эквивалентно выполнению всего лишь одной:

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

На рис. 6.6 представлена программа, приведенная ранее на рис. 5.10, модифицированная путем внесения в нее команд EQU, присваивающих символические имена регистрам. При этом используются обозначения блок-схемы рис. 5.5.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *