Выражения


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

 

Например, во фрагменте программы:

MemVar DB 0

NextVar DB ?

mov ax,SEG MemVar

mov ds,ax

mov bx,OFFSET MemVar + (3*2) — 5)

mov BYTE PTR [bx],1

операция SEG используется для загрузки постоянного значения сегмента, в котором находится MemVar, и копирования этого значения из регистра AX в DS. Далее в этой программе используется сложное выражение, включающее в себя операции *, +, — и OFFSET, при вычислении которого получается значение OFFSET MemVar+1, которое представляет собой ни что иное, как адрес NextVar. Наконец, для выбора байтовой операции при сохранении константы 1 в ячейке, на которую указывает регистр BX (что представляет собой NextVar), используется операция BYTE PTR.

Относительно выражений стоит сделать важное замечание: при вычислении всех выражений должно получаться значение-константа. OFFSET MemVar — это значение-константа, представляющее собой сме-щение переменной MemVar в ее сегменте. Кроме того, в то время как сохраненное в переменной MemVar значение может изменяться, сама переменная MemVar, конечно, никуда не перемещается.

Так как значения-константы точно известны, Турбо Ассемблер может вычислять состоящие из постоянных значений выражения так же, как он ассемблирует ваш исходный код. Для Турбо Ассемблера выражение OFFSET MemVar + 2 совершенно аналогично выражению 5 + 2. Поскольку все элементы выражения неизменяемы и определены во время ассемблирования, выражение можно свести к одному значению-константе.

В выражениях могут использоваться следующие операции:

<>, (), LENGTH, MASK, SIZE, WIDTH

. (селектор элемента структуры)

HIGH, LOW

: (переопределение сегмента)

OFFSET, PTR, SEG, THIS, TYPE *, /, MOD, SHL, SHR +, — (бинарные)

EQ, GE, GT, LE, LT, NE

NOT

AND

OR, XOR

LARGE, SHORT, SMALL, .TYPE

Названия и обозначения некоторых операций говорят сами за себя. Эти операции выполняют в арифметических выражениях именно те действия, для которых они предназначены. Операции мы поясним в этой главе позднее, когда до них дойдет дело. Кроме того, ответы на вопросы, касающиеся отдельных операций, можно найти в Главе 2 «Справочного руководства».

Операнды-метки

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

Например:

MemWord DW 1

mov al,SIZE MemWord

Здесь значение 2 (размер в байтах переменной в памяти MemWord) помещается в AL. В данном контексте метка может становиться частью выражения, как уже показано в предыдущем разделе.

Метки могут также использоваться в качестве целевых операн-дов в операциях CALL и JMP. Например, во фрагменте программы:

cmp ax,100

ja IsAbove100

IsAbove100:

инструкция JA используется для перехода по адресу, заданному операндом IsAbove100, если значение AX превышает 100. Здесь метка используется в качестве константы, задавая адрес перехода.

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

TampVar DW ?

mov [TempVar],ax

sub ax,[TempVar]

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

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

Загрузка...