Операнды – выражения

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

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

 

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

Оператор Приоритет
LENGTH, SIZE, WIDTH, MASK, (,), [,], <, >
.
:
PTR, OFFSET, SEG, TYPE, THIS
HIGH, LOW
+,- (унарные)
*, /, MOD, SHL, SHR

 


 

Дадим краткую характеристику операторов. В приложении Б (http://www.piter.com/download) для сравнения и информации приведены сведения об операторах и предопределенных символах транслятора MASM. • Арифметические операторы (рис. 5.5). К арифметическим операторам относят­ся унарные и бинарные операторы «плюс» (+) и «минус» (-), а также операто­ры умножения (*), целочисленного деления (/), получения остатка от деления (MOD). Эти операторы в табл. 5.1 соответствуют уровням приоритета 6, 7, 8. Например,

 

Рис. 5.5. Синтаксис арифметических операторов

 

 

 
· Операторы сдвига выполняют сдвиг выражения на указанное количество раз­рядов (рис. 5.6).   Например, mask_b equ 10111011 ……. mov al.mask_b shr 3 ; al=00010111

· операторы сравнения возвращают значение «истина» или «ложь» и предназначены для формирования логических выражений (рис. 5.7 и табл. 5.2). Логическое значение «истина» соответствует логической единице, а «ложь» — логическому нулю. Логическая единица — значение, все биты которого равны 1, соответственно, логический нуль — значение, все биты которого равны 0.

Например,

 

tab_sizeequ 30 ; размер таблицы

……

mov al, tab_size ge 50 ; загрузка размера таблицы в al
cmр al, 0 ; если tab_size < 50, то

je m1 ; переход на m1

------------

M1:

В этом примере, если значение tab_size больше или равно 50, то результат в AL равен 0ffh, а если tab_size меньше 50, то результат в AL равен 00h. Команда CMP сравнивает значение AL с нулем и устанавливает соответствующие флаги в FLAGS/ EFLAGS. Команда JE на основе анализа этих флагов передает или не передает управление на метку m1.

 


 

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

Оператор Значение
Eg Истина, если выражение_1 равно выражение_2
Ne Истина, если выражение_1 не равно выражение_2
Li Истина, если выражение_1 меньше выражение_2
Le Истина, если выражение_1 меньше или равно выражение_2
Gr Истина, если выражение_1 больше выражение_2
Ge Истина, если выражение_1 больше или равно выражение_2

 

Логические операторы выполняют над выражениями побитовые операции (рис. 5.8). Выражения должны быть абсолютными, то есть такими, численное значение которых может быть вычислено транслятором. Например, flags equ 10010011 mov al, flags xor 01h ; al = 10010010; пересылка в al поля flags; ; с инвертированным правым битом   Более подробные сведения о правилах, в соответствии с которыми вычисляется результат логических операций, приводятся в главе 9.  

 

 

Рис. 5.8. Синтаксис логических операторов

· Индексный оператор. Как показанона рис. 5.9, квадратные скобки транслятор воспринимает как указание сложить значение выражение_1 за этими скобками со значением выражение_2, заключенным и скобки. Например, mov ax.mas[si] ; пересыпка слова по адресу mas + (si) в регистр ах

 

 

Примечание В литературе принято следующее соглашение: когда в тексте речь идет о содержимой регистра, то его название берут в круглые скобки. К npи-меру, в нашем случае запись в тексте комментария последнего фрагмен­та Программы mas + (si) означает вычисление выражения, составляю­щего значение смешения символического имени mas плюс содержимое регистра SI.

· Оператор переопределения типа PTR применяется для переопределения или уточнения тина метки (или переменной), определяемой выражением (рис. 5.10). Тип может принимать одно из следующих значении: BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR (что означают эти значения, вы узнаете далее в этой главе).

Например,

d_wrd dd 0

…….

mov al.byte ptr d_wrd+l ; пересылка второго байта из двойного слова

 

Поясним этот фрагмент программы. Переменная d_wrd имеет тип двойного сло­ва. Что делать, если возникнет необходимость обращения не ко всему значе­нию переменной, а только к одному из входящих в нее байтов (например, ко второму)? Если попытаться сделать это командой mov al, d_wrd+l, то транслятор выдаст сообщение о несовпадении типов операндов. Оператор PTR позволяет непосредственно в команде переопределить тип и выполнить команду.

 


Тип ptr Выражение

 

Рис. 5.10. Синтаксис оператора переопределения типа

· Оператор переопределения сегмента заставляет вычислять физический адрес относительно конкретно задаваемой сегментной составляющей: «имя сегмент­ного регистра», «имя сегмента» из соответствующей директивы SEGMENT или «имя группы» (рис. 5.11).

Рис. 5.11. Синтаксис оператора переопределения сегмента

Этот момент важен, поэтому поясним его подробнее. При обсуждении сегмен­тации (см. главу 2) упоминалось о том, что процессор на аппаратном уровне поддерживает три типа сегментов — кода, стека и данных. В чем заключается такая аппаратная поддержка? К примеру, для выборки на выполнение очередной коман­ды процессор должен обязательно посмотреть содержимое сегментного регистра CS, и только его. В этом регистре содержится информация о начале сегмента ко­манд. В реальном режиме работы процессора в сегментном регистре CS находится не сдвинутый на четыре бита влево физический адрес начала сегмента. Для полу­чения адреса конкретной команды процессору остается умножить содержимое CS на 16 (что означает сдвиг на четыре разряда) и сложить полученное 20-разрядное значение с 16-разрядным содержимым регистра IP. Примерно то же самое проис­ходит и тогда, когда процессор обрабатывает операнды в машинной команде. Если он видит, что операнд — это адрес (эффективный адрес, который является только частью физического адреса), то он знает, в каком сегменте его искать, — по умол­чанию это сегмент, адрес начала которого записан в сегментном регистре DS. В за­щищенном режиме сегментные регистры содержат селекторы, с помощью кото­рых также можно получить доступ к информации об адресе начала сегмента.

А что же с сегментом стека? Для большей ясности стоит вернуться к вопросу о регистрах общего назначения (см. главу 2). В контексте нашего рассмотрения ин­терес представляют регистры SP и ВР. Если процессор видит в качестве операнда (или его части, если операнд — выражение) один из этих регистров, то по умолча­нию он формирует физический адрес операнда, используя содержимое регистра SS как сегментную составляющую этого адреса. Что подразумевает термин «по умолчанию»? Вспомним (см. главу 1) набор микропрограмм в блоке микропро­граммного управления, каждая из которых выполняет одну из команд в системе машинных команд процессора. Каждая микропрограмма работает по своему алгоритму. Изменить его, конечно же, нельзя, но можно чуть-чуть подкорректировать. Делается это с помощью необязательного поля префикса машинной команды (см. раздел «Формат машинных команд IA-32» в главе 3). Если программист согласен с тем, как работает команда, то это поле отсутствует. Если же есть необходимость внести поправку (если, конечно, она допустима для конкретной команды) в алгоритм работы команды, то необходимо сформировать соответствующий префикс.

Префикс представляет собой однобайтовую величину, численное значение кото­рой определяет ее назначение. Процессор распознает по указанному значению, что этот байт является префиксом, и дальнейшая работа микропрограммы выполня­ется с учетом поступившего указания на корректировку ее работы. В главе 3 мы перечислили все возможные префиксы машинных команд. В контексте нашего обсуждения интерес представляет один из них — префикс замены сегмента. Его назначение состоит в том, чтобы указать процессору (а по сути, микропрограмме) на то, что мы не хотим использовать сегмент по умолчанию. Возможности для подобного переопределения, конечно, ограничены. Сегмент команд переопределить нельзя, адрес очередной исполняемой команды однозначно определяется парой CS:IP. А вот сегменты стека и данных — можно. Для этого и предназначен оператор переопределения сегмента (:). Транслятор ассемблера, обрабатывая этот оператор, формирует соответствующий однобайтовый префикс замены сегмента и ставит его перед машинным представлением соответствующей команды ассемблера. Например,

 

.code

…….

jmp metl ; обход обязателен, иначе поле ind

; будет трактоваться как очередная команда

ind db5 ; описание поля данных в сегменте команд

met1:

……..

Mov al, cs : ind ; переопределение сегмента позволяет работать

; с данными. определенными внутри сегмента кода

 

Продолжим перечисление операторов.

· Оператор именования типа структуры также заставляет транслятор произво­дить определенные вычисления, если он встречается в выражении. Подробно этот оператор (.) описывается в главе 13 при обсуждении сложных типов дан­ных.

· Оператор получения сегментной составляющей адреса выражения возвращает физический адрес сегмента для выражения, в качестве которого могут высту­пать метка, переменная, имя сегмента, имя группчестве которого могут высту­пать метка, переменная, имя сегмента, имя группы или некоторое символиче­ское имя (рис. 5.12).

 


SEG Выражение

Рис, 5.12. Синтаксис оператора получения сегментной составляющей

 

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

 

 


offset Выражение

 

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

 

Например,

.data

pole dw 5

.Code ……. mov ax, seg pole mov es, ax mov dx, offset pole

 

 

; теперь в паре es:dx полный адрес pole

 

Контрольные вопросы

1. Операнды – выражения, определение, приоритеты операторов, порядок изменения приоритетов?

2. Арифметические операторы – определение, уровни приоритета, пример, синтаксис арифметических операторов?

3. Операторы сдвига - определение, уровни приоритета, пример, синтаксис операторов сдвига?

4. операторы сравнения - определение, уровни приоритета, пример, синтаксис операторов сравнения?

5. Таблица значений операторов сравнения?

6. Логические операторы - определение, уровни приоритета, пример, синтаксис логических операторов?

7. Индексный оператор - определение, уровни приоритета, пример, синтаксис индексного оператора?

8. Оператор переопределения типаPTR - определение, уровни приоритета, пример, синтаксис?

9. Оператор переопределения сегмента - определение, уровни приоритета, пример, синтаксис?

10. Оператор именования типа структуры – назначение?

11. Оператор получения сегментной составляющей адреса выражения – назначение, синтаксис?

12. Оператор получения смещения выражения – назначение, синтаксис, пример?