- •3.Программирование на языке ассемблера
- •3.1. Архитектура микропроцессоров k1810вм86/k1810вм88
- •3.2. Основные элементы ассемблера. Формат программной строки
- •3.3. Директивы управления сегментами
- •3.4. Типовая структура текста программы
- •3.5. Символические имена
- •3.6. Константы. Их типы и директивы описания
- •3.6.1. Числовые константы
- •3.6.2. Символьные константы
- •3.6.3. Поименованные константы
- •3.6.4. Константы-выражения
- •3.7. Переменные. Их типы и директивы описания
- •3.7.1. Стандартные типы данных и их размещение в памяти
- •3.7.2. Директивы описания переменных и распределения памяти
- •3.8. Атрибуты переменных и меток. Директивы, возвращающие атрибутные значения
- •3.8.1. Атрибуты переменных
- •3.8.2. Атрибуты меток
- •3.9. Замена атрибутов переменных и меток
- •3.9.1. Замена смещения
- •3.9.2. Замена сегмента
- •3.9.3. Замена типа
- •3.10. Способы адресации операндов
- •3.10.1. Адресация данных
- •Регистровая адресация
- •Непосредственная адресация
- •Прямая адресация
- •Косвенная регистровая адресация
- •Базовая адресация
- •Индексная адресация
- •Базово-индексная адресация
- •Относительная базовоиндексная адресация
- •3.10.2. Адресация переходов
- •Внутрисегментный прямой переход
- •Внутрисегментный косвенный переход
- •Межсегментный прямой переход
- •Межсегментный косвенный переход
- •3.11. Система команд
3.2. Основные элементы ассемблера. Формат программной строки
Основными элементами ассемблера являются директивы ассемблера и команды МП.
Команды описывают действия МП в процессе выполнения программы и всегда порождают машинный код в памяти системы.
Директивы служат для сообщения информации, необходимой в процессе трансляции программы. Они обеспечивают резервирование ячеек памяти, назначение имен, распределение сегментных регистров и т.д. Особенностью директив является то, что они, как правило, не порождают машинный код в памяти системы и поэтому часто называются псевдокомандами.
Программа на ассемблере представляет собой совокупность строк. Каждая строка содержит лишь одну команду МП или директиву ассемблера.
Формат командной строки имеет вид:
{МЕТКА:} {ПРЕФИКС} КОМАНДА {ОПЕРАНДЫ} {;КОММЕНТАРИЙ}
Здесь и далее фигурные скобки показывают необязательность заключенного в них элемента.
МЕТКА это определенное программистом имя, используемое для пометки данной команды. Значением метки является адрес помеченной команды. Метки всегда заканчиваются двоеточием и используются в качестве операндов в командах передачи управления.
ПРЕФИКС в этом поле помещается один из программных префиксов: префикс повторения REP или префикс блокировки LOCK, которые предшествуют команде и вызывают соответствующие действия.
КОМАНДА в этом поле указывается мнемоническое имя команды, определяющее выполняемые действия.
ОПЕРАНДЫ в этом поле описываются данные, над которыми выполняется операция, предписанная командой.
КОММЕНТАРИЙ любая последовательность символов, начинающаяся с ;. Комментарий не влияет на выполнение команды и предназначен для пояснения выполняемых действий в контексте данной точки программы.
Формат директивной строки ассемблера имеет вид:
{ИМЯ} ДИРЕКТИВА {ОПЕРАНДЫ} {;КОММЕНТАРИЙ}
ИМЯ это идентификатор каких-либо данных. Имя данных не имеет ничего общего с меткой и двоеточием не заканчивается.
ДИРЕКТИВА это поле содержит мнемоническое имя директивы, определяющее действия, выполняемые ассемблером в процессе трансляции программы.
Поля ОПЕРАНДЫ и КОММЕНТАРИЙ аналогичны соответствующим полям командной строки.
Все поля программной строки должны разделяться по меньшей мере одним пробелом или знаком табуляции. Программная строка может начинаться не с первой позиции. Ее длина не должна превышать 132 знака.
3.3. Директивы управления сегментами
В связи с сегментацией памяти программа представляет собой совокупность логических сегментов.
Логический сегмент это поименованная область памяти, адресуемая при неизменном значении сегментного регистра. Размеры логического сегмента не могут превышать размеров физического сегмента и составляют от 0 до 64 кбайт.
Для описания логических сегментов предназначены директивы ассемблера SEGMENTиENDS. Формат описания логического сегмента имеет вид:
Имя_сегмента SEGMENT
. . . . . . ; Содержимое логического
. . . . . . ; сегмента
Имя_сегмента ENDS
Директива SEGMENTприсваивает логическому сегменту указанное имя и открывает его, а директиваENDSзакрывает сегмент с указанным именем. Все данные или команды, находящиеся между директивамиSEGMENTиENDSс одним и тем же именем, принадлежат этому сегменту.
Как правило, логические сегменты не имеют общих частей. Однако, допускается их вложенность и не допускается их пересечение.
Пример 3.1:
1. Описание неперекрывающихся сегментов:
Data1 SEGMENT
. . . . . .
Data1 ENDS
Data2 SEGMENT
. . . . . .
Data2 ENDS
2. Описание вложенных сегментов:
Data1 SEGMENT
. . . . . .
Data2 SEGMENT
. . . . . .
Data2 ENDS
. . . . . .
Data1 ENDS
После описания логических сегментов необходимо связать их с сегментными регистрами, которые будут использоваться для их адресации. Для этого предназначена директива ASSUME, которая записывается в следующем формате:
ASSUME Cегментный_регистр:Имя_сегмента
{,Сегментный_регистр:Имя_сегмента . . .}
где Сегментный_регистр имя одного из сегментных регистров CS, DS, ES, SS;
Имя_сегмента имя логического сегмента, указанное в директиве
SEGMENT.
Пример3.2:
ASSUMECS:Code, DS:Data1, ES:Data2, SS:Stack ;Связывание регист-
;ров и сегментов
Эта строка указывает, что для адресации сегмента Code будет использоваться сегментный регистр CS, сегмента Data1 регистр DS, сегмента Data2регистр ES и сегмента Stackрегистр SS.
Допускается связывать один и тот же логический сегмент с несколькими сегментными регистрами, что соответствует совмещению сегментов памяти.
Пример3.3:
ASSUMECS:Code, DS:Data, ES:Data ; Совмещение основного и
; дополнительного сегментов
Здесь один и тот же логический сегмент Data связан с регистрами DS и ES и, следовательно, одновременно является и основным, и дополнительным сегментом данных в памяти, что соответствует их совмещению.
Использование директивы ASSUMEисключает необходимость указания сегментных регистров всякий раз, когда необходимо получить доступ к содержимому того или иного сегмента в памяти. Нужный сегментный регистр выбирается автоматически в соответствии с ее назначениями.
В программе может быть несколько директив ASSUME. Как правило, она используется в начале программы и гораздо режев ее дальнейшем тексте. ДирективаASSUME необходима в тех точках программы, начиная с которых используются другие логические сегменты по отношению к текущим сегментам.
Директива ASSUMEне загружает начальные адреса логических сегментов в соответствующие сегментные регистры. Поэтому во все сегментные регистры, кроме CS, загрузка базовых адресов сегментов должна осуществляться явно. Это реализуется с помощью команд пересылки данных MOV.
Пример3.4:
MOV AX, Data1 ; Инициализация сегментных
MOV DS, AX ; регистров
ASSUME DS:Data1
MOV DX, <Данные из сегмента Data1>
MOV AX, Data2
MOV DS, AX
ASSUMEDS:Data2
MOV DX, <Данные из сегмента Data2>
В этом примере сначала осуществляется инициализация регистра DS на базовый адрес сегмента Data1, а затем на адрес сегмента Data2. Значения Data1 и Data2 являются константами, и их пересылка в DS осуществляется через промежуточный регистр AX. После инициализации DS на базовый адрес некоторого сегмента можно обращаться к находящимся в нем данным.
Доступ к переменным, находящимся в логических сегментах, не связанных с сегментными регистрами, невозможен. Ранее установленную связь между сегментным регистром и логическим сегментом можно разорвать с помощью той же директивы ASSUME, записывая директивуNOTHINGвместо имени сегмента.
Пример3.5:
ASSUMEDS:NOTHING
Эта строка разрывает ранее установленную связь между регистром DS и логическим сегментом Data1 (см. пример 3.3), что делает невозможным обращение к данным из этого сегмента.