Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МУ_ЛЕК.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
801.79 Кб
Скачать

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

В языке Ассемблера существуют команды и директивы, формат которых практически одинаков. В командах Имя интерпретируется как метка, поэтому за ней всегда ставится символ двоеточия ':'. Для Ассемблера в качестве имени (идентификатора) допускаются следующие символы:

  • Латинские буквы от A(a) до Z(z) — РЕГИСТР БЕЗРАЗЛИЧЕН. Ассемблер сам по себе НЕ различает ПРОПИСНЫЕ и строчные буквы. Но при использовании ассемблерных модулей в программе на алгоритмическом языке, чувствительном к регистру букв, например, в С/С++, буквы в разных регистрах будут разными.

  • Цифры от 0 до 9.

  • Специальные символы: ? . @ _ $.

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

При ассемблировании между директивами и командами существует одно принципиальное различие. Директивы (псевдооператоры, псевдокоманды) управляют работой компилятора или компоновщика, а НЕ микропроцессора. Они используются, например, для сообщения компилятору, какие константы и переменные применяются в программе и какие имена мы им дали, какой сегмент является кодовым, а какой — сегментом данных или стека, в каком формате выводить листинг исходного кода программы и прочее. Большинство директив НЕ генерирует машинных команд (объектный код).

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

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

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

  • Терминальные элементы языка (название директив и команд, разделительные знаки) будем выделять жирным шрифтом.

  • Нетерминальные элементы (название параметров, операндов и других атрибутов) выделим курсивом.

  • Комментарии будем писать обычным шрифтом.

  • Необязательные элементы заключаются в квадратные скобки []. В синтаксисе языка Ассемблера есть и терминальный элемент квадратные скобки [] — в этом случае это будет особо ПОДЧЕРКНУТО.

  • Повторяющиеся элементы синтаксической структуры описываются многоточием (…).

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

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

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

Универсальная директива для описания сегмента имеет следующий формат:

имяС SEGMENT [параметры] ; начало СЕГМЕНТА имяС

.

.

.

имяС ENDS ; конец СЕГМЕНТА имяС

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

  • для сегмента кода CSEG или CODE;

  • для сегмента данных DSEG или DATA;

  • для сегмента стека STACK.

Директива ENDS обозначает конец сегмента. Обе директивы SEGMENT и ENDS должны иметь одинаковые имена имяС.

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

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

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

Таблица 4.1. Параметр выравнивания (align)

Параметр

Значение

BYTE

Выравнивание НЕ выполняется. Сегмент размещается, начиная со следующего байта.

WORD

Начало сегмента выравнивается на границу слова (четный адрес, кратный 2)

DWORD

Начало сегмента выравнивается на границу двойного слова (четный адрес, кратный 4)

PARA

Начало сегмента выравнивается на границу параграфа (четный адрес, кратный 16). Это значение принято по умолчанию.

PAGE

Начало сегмента выравнивается на границу страницы (четный адрес, кратный 256)

MEMPAGE

Начало сегмента выравнивается на границу страницы памяти (четный адрес, кратный 4K)

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

3. Класс ('class'). Данный элемент, заключенный в апострофы, используется для группирования сегментов при компоновке. Компоновщик группирует вместе все сегменты с ОДИНАКОВЫМ классом.

Таблица 4.2. Параметр объединения (combine)

Параметр

Значение

PRIVATE

Сегмент НЕ будет объединяться с сегментами с тем же именем, находящимися в других модулях. Это значение принято по умолчанию.

PUBLIC

Сегмент будет объединяться с сегментами с тем же именем, находящимися в других модулях или в том же модуле, в один сегмент.

MEMORY

Параметр подобен PUBLIC, но для сегмента стека.

COMMON

Размещает данный сегмент и все сегменты с тем же именем по ОДНОМУ и тому же адресу. Получаются перекрывающиеся сегменты (overlay), занимающие разделяемую область памяти (shared memory).

VIRTUAL

Описывает сегмент специального вида, который должен объявляться ВНУТРИ другого сегмента (общая область памяти).

AT xxx

Устанавливает сегмент по абсолютному адресу параграфа xxx для получения доступа по идентификаторам к фиксированным адресам памяти (например, видеобуфер, таблица векторов прерываний – см. прил.6)

Например, сегмент стека, в котором зарезервировано 100*8 = 800 байтов (со словом My Stack — 8 символов) может быть описан следующим образом:

SStack SEGMENT PARA PUBLIC 'Stack'

DB 100 dup ('My Stack')

SStack ENDS

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]