Синтаксис ассемблерных команд
Важным отличием ассемблерных выражений от выражений Турбо Паскаля является то обстоятельство, что они должны быть статическими, т.е. разрешены (вычислены) на этапе создания программы. Если выражение может быть полностью вычислено к моменту его трансляции, т.е. если оно состоит только из регистровых или непосредственных значений, такое выражение называется абсолютным, компилятор вычисляет его и использует для создания команды.
В ходе компиляции программы вырабатывается так называемый объектный код, который затем преобразуется компоновщиком в готовую к работе программу. При создании объектного кода компилятор не может вычислить значения выражений типа "ссылка на память", так как не знает окончательного положения в памяти меток, переменных, подпрограмм. В результате он создает так называемое перемещаемое выражение, которое затем компоновщиком преобразуется в нужную ссылку на память.
Встроенный ассемблер разрешает любую операцию над абсолютным значением (см. ниже), но ограничивает перемещаемые выражения до сложения или вычитания, одним из операндов которого должна быть константа.
Другое важное отличие ассемблерных выражений от выражений Турбо Паскаля заключается в способе интерпретации переменных. В выражениях Паскаля любая ссылка на переменную интерпретируется как текущее содержимое этой переменной. В ассемблерных выражениях это справедливо только тогда, когда все выражение в целом состоит из имени переменной. Во всех остальных случаях ссылка на переменную интерпретируется как адрес переменной. Например, выражение:
х+10
В Паскале означает: "к содержимому переменной X прибавить 10". В ассемблерной команде это означает:."к адресу (смещению) переменной X прибавить 10". Однако команда:
mov ах,X
Означает: "поместить в регистр АХ первые два байта переменной X". Если бы нам понадобилось загрузить в АХ адрес переменной X, мы должны были бы написать:
mov ax,OFFSET X
Замечу, что попытка "перехитрить" ассемблер командами типа:
mov ax,X+0 mov ax,X+1-1
И т.п. не дает желаемого результата: ассемблер просто загружает в АХ содержимое переменной X.
Как и в Паскале, ассемблерные выражения имеют тип, но в отличие от Паскаля этот тип определяет только размер объекта в памяти и не ограничивает применяемые к нему операции.
Встроенный ассемблер имеет следующие предопределенные типы:
Тип | Длина в памяти |
---|---|
BYTE | 1 |
WORD | 2 |
DWORD | 4 |
QWORD | 8 |
TBYTE | 10 |
NEAR | |
FAR |
Имена предопределенных типов можно использовать для приведения типов выражений. Например, если определены переменные:
var Flag: Boolean; X: Word;
То такие ассемблерные выражения недопустимы:
mov Flag,bx mov ah,X
Для корректного задания последней команды можно использовать следующие варианты:
mov ah,BYTE PTR X mov ah,Byte(X) mov ah,X.Byte
Во всех случаях в АН будет загружен первый (младший) байт переменной X. Встроенный ассемблер поддерживает операции, перечисленные в следующей таблице (в порядке убывания приоритета).