Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000239.doc
Скачиваний:
23
Добавлен:
30.04.2022
Размер:
1.12 Mб
Скачать

2.5. Выражения

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

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

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

TX DB 2

лучше использовать эквивалентную ей директиву

ТХ DB TYPE X

поскольку она более универсальна и ее не надо менять, если изменится тип переменной X.

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

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

По структуре и назначению выражения, константные и адресные, можно разделить на простейшие выражения и операторы. Из простейших выражений строятся любые другие выражения. К простейшим выражениям относятся числа, имена констант, имена переменных и т. п. Термином «оператор» в языке ассемблера принято обозначать то, что мы обычно называем функциями и операциями. Операторы языка ассемблера делятся на одноместные (это аналог функций одного аргумента) и двухместные (это аналог бинарных операций); примером может служить TYPE X или А+1. С помощью операторов из простейших выражений строятся более сложные выражения.

О простейших выражениях и операторах будет рассказано далее. Однако уже сейчас следует указать старшинство всех операторов языка ассемблера (в порядке убывания; в каждой строке указаны операторы одного старшинства):

1. (), [ ], LENGTH, SIZE, WIDTH, MASK

2. .

3. :

4. PTR, OFFSET, SEG, TYPE, THIS

5. HIGH, LOW

6. одноместные + и -

7. *, /, MOD, SHL, SHR

8. двухместные + и -

9. EQ, NE, LT, LE, GT, GE

10. NOT

11. AND

12. OR, XOR

13. SHORT, TYPE

Операторы одного старшинства вычисляются слева направо. Например, А+В-С - это (А+В) - С.

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

Значениями константных выражений всегда являются 16-битовые целые числа (единственным исключением является директива DD, в которой можно явно ука­зывать 32-битовые числа). При этом, если значением (в математическом смысле) константного выражения является отрицательное число, то в формируемую машинную программу оно записывается в дополнительном коде.

К простейшим константным выражениям относятся:

– число от -215 до 216-1 (числа вне этого диапазона рассматриваются как ошибка);

– символ (значением такого выражения является код символа; например, значением выражения '0' будет число 30h);

– строка из двух символов (значением является число-слово, составленное из кодов этих символов; например, значением выражения '01' будет число 3031h);

– имя константы (значением такого выражения является значение константы; например, если была директива К EQU 10, то значение К равно 10).

Другие простейшие константные выражения будут рассмотрены позже.

Среди константных операторов, т. е. операторов с числовым значением, пока следует отметить уже известный оператор TYPE и следующие арифметические операторы (k, kl и k2 означают любые константные выражения):

– одноместные плюс и минус: +k, -k

– операторы сложения и вычитания: kl+k2, kl-k2

– операторы умножения и деления: kl *k2, kl/k2, kl MOD k2

(* - умножение, / - деление нацело, MOD - взятие остатка от деления)

Пример использования константного выражения с арифметическими операторами:

K EQU 30

X DB (3*K-l)/2 DUP(?) ;массив из 44 байтов

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

Пример:

X DW 1,2,3,4,5

Y DB ?

SIZE_X EQU Y-X ; SIZE_X = 10

Вычитание адресов используется обычно для определения расстояния (числа бантов) между этими адресами. В нашем случае разность Y-X показывает, сколько байтов занято всеми элементами массива X.

Следует отметить одну особенность арифметических операторов: все они выполняются в области 16-битовых чисел, т. е. от результата всегда берутся только последние 16 битов (остаток от деления на 216, на 10000h), например:

(2*9000h)/100h=(12000h)/100h>2000h/100h=20h(a не 120h)

Адресные выражения

Значениями адресных выражений являются 16-битовые адреса. Все операции над адресами выполняются по модулю 216 (10000h).

К простейшим адресным выражениям относятся:

– метка (имя команды) и имя переменной, описанное в директиве DB,DW или DD (значениями таких выражений являются адреса меток и имен);

– счетчик размещения; он записывается как $ и обозначает адресного предложения, в котором он встретился. При трансляции программы ассемблер следит за тем, в ячейку с каким адресом должен попасть машинный эквивалент очередного предложения программы на языке ассемблера; так вот, если необходимо сослаться на этот адрес, то и надо указать $. Отсюда следует, что в разных предложениях $ обозначает разные адреса. Например, если адрес переменной А равен 100h, то имеем

A DW $ ;эквивалентно A DW 100h

В DW $ ;эквивалентно В DW 102h

Чаше всего счетчик размещения используется для вычисления размера памяти, занимаемой каким-то массивом, например:

X DW 40 DUP(?)

SIZE_X EQU $-X ; SIZE_X = 80

Здесь $ обозначает адрес первого байта за массивом X, из этого адреса и вычитается начальный адрес массива.

Среди операторов, значением которых являются адреса, пока следует отметить лишь операторы сложения и вычитания (a - адресное выражение, k - константное):

сложение адреса с числом: a+k, k+а (значением такого выражения является адрес, полученный прибавлением к адресу a числа k).

вычитание константы из адреса: а-k (значением является адрес а, уменьшенный на величину k).

Адресные выражения вида <имя>±<целое> используются для ссылок на безы­мянные ячейки памяти (как правило, элементов массивов). Например, если имеются описания

A DB 0,1,2,3

В DB 4

то именованными оказываются только байты со значениями 0 и 4, а остальные элементы массива А оказываются безымянными, поэтому к ним нельзя обратиться по имени. Для доступа к таким безымянным ячейкам в языке ассемблера и используются адресные выражения указанного вида. Например, сослаться на байт со значением 3 можно с помощью выражения А+3 или В-1.

Отметим, что в языке ассемблера запрещено вычитание адреса из числа, не допускается сложение, умножение и деление адресов - все это бессмысленные операции. Однако допускается вычитание адресов, но в этом случае, как мы уже знаем, результатом будет не адрес, а константа.

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