лабораторные на Pasca (Кудрявцев)l
.pdfВстроенный ассемблер |
343 |
|
|
Операнды
Операндами встроенного ассемблера могут быть выражения, со- стоящие из комбинации регистров, констант, имен и символов опе- раций.
Регистры
Во встроенном ассемблере используется мнемоника регистров, ука- занная выше, а также имя ST для ссылки на регистры арифметиче- ского сопроцессора.
Константы
Ассемблер поддерживает строковые и числовые константы. Стро- ковые константы заключаются в апострофы или кавычки. Если константа объявлена с помощью кавычек, внутри нее символ апо- строф рассматривается наравне с другими символами, т.е. не счита- ется ограничителем константы, точно так же внутри константы, об- рамленной апострофами, не считается ограничителем символ ка- вычки. Если внутри константы необходимо указать ограничиваю- щий ее символ, он удваивается. Примеры:
'Строковая константа' "ЭТО - ТОЖЕ СТРОКОВАЯ КОНСТАНТА"
'Символ '' не считается ограничителем' 'внутри строки, обрамленной кавычками "..." '
Числовые константы могут быть только целыми и их значение не может превосходить емкости двойного слова, т.е. должно быть
внутри диапазона
-2 147 483 648 … +4 294 967 295.
По умолчанию при записи числовых констант используется деся- тичная нотация, но ассемблер поддерживает также двоичные, вось- меричные и шестнадцатеричные константы. Двоичная константа составляется как комбинация единиц и нулей, заканчивающаяся символом В (от Binary – двоичный); при записи восьмеричной кон- станты используются символы 1...7, а в ее конце ставится символ О (Octal – восьмеричный); шестнадцатеричная константа записывает- ся по правилам Турбо Паскаля (начинается с символа #) либо по правилам Турбо Ассемблера: начинается с цифры, в конце ставится символ Н (от Hexadecimal – шестнадцатеричный).
344 |
Приложение |
|
|
Имена
Локальные метки – это единственные имена, которые разрешается определять внутри ассемблерного оператора. Имена остальных объектов программы – констант, переменных, подпрограмм – должны определяться только с помощью средств Турбо Паскаля.
Область определения имен подчиняется тем же правилам, что и в Турбо Паскале – имена должны быть «видны» в том месте, где они используются, и они локализуются в пределах блока, в котором описаны.
Во встроенном ассемблере могут использоваться три предопреде- ленных имени:
@Code |
– текущий сегмент кода |
@Data |
– начальный сегмент данных |
@Result |
– ссылка внутри функции на ее результат |
Имена @Code и @Data могут использоваться только в сочетании с директивой SEG для ссылки на нужный сегмент. Например:
asm
mov ax, SEG @Data mov ds, ax
end;
Имя @Result используется для присвоения результата функции. Например:
Function Min(X,Y: Integer): Integer; |
{Эта функция сравнивает два целых числа и |
Begin |
возвращает наименьшее из них} |
|
|
Asm |
{Помещаем Х в АХ} |
mov ах, Х |
|
cmp ax, Y |
{X<Y ?} |
jl @ |
{Да - на выход} |
mov ax, Y |
{Нет - помещаем Y в АХ} |
@: mov @Result, ax |
{AX содержит результат} |
End |
|
end; |
|
Для доступа к полям записей разрешается использование составных имен. Например:
Type
Point = record
Встроенный ассемблер |
347 |
|
|
средственных значений, такое выражение называется абсолютным, компилятор вычисляет его и использует для создания команды.
В ходе компиляции программы вырабатывается так называемый объектный код, который затем преобразуется компоновщиком в го- товую к работе программу. При создании объектного кода компи- лятор не может вычислить значения выражений типа «ссылка на память», так как не знает окончательного положения в памяти ме- ток, переменных, подпрограмм. В результате он создает так назы- ваемое перемещаемое выражение, которое затем компоновщиком преобразуется в нужную ссылку на память.
Встроенный ассемблер разрешает любую операцию над абсолют- ным значением (см. ниже), но ограничивает перемещаемые выра- жения до сложения или вычитания, одним из операндов которого должна быть константа.
Другое важное отличие ассемблерных выражений от выражений Турбо Паскаля заключается в способе интерпретации переменных. В выражениях Паскаля любая ссылка на переменную интерпрети- руется как текущее содержимое этой переменной. В ассемблерных выражениях это справедливо только тогда, когда все выражение в целом состоит из имени переменной. Во всех остальных случаях ссылка на переменную интерпретируется как адрес переменной. Например, выражение
Х+10
ВПаскале означает: «к содержимому переменной Х прибавить 10».
Вассемблерной команде это означает: «к адресу (смещению) пере-
менной Х прибавить 10». Однако команда
mov ах, Х
означает: «поместить в регистр АХ первые два байта переменной X». Если бы нам понадобилось загрузить в АХ адрес переменной X,
мы должны были бы написать
mov ax, OFFSET X
Заметим, что попытка «перехитрить» ассемблер командами типа
mov ах, Х+0 mov ах, Х+1-1
Встроенный ассемблер |
349 |
|
|
Операции встроенного ассемблера
Операция |
Комментарий |
|
|
& |
Перекрытие идентификатора |
( ) |
Подвыражение |
[ ] |
Ссылка на память |
. (точка) |
Селектор структуры |
HIGH LOW |
Доступ к байту в слове |
+ - |
Унарные операции задания знака |
: |
Перекрытие сегмента |
OFFSET SEG TYPE PTR * |
|
/ MOD SHL SHR |
|
+ - |
Бинарные операции |
NOT AND OR XOR |
Операции над битами |
|
|
Операция &
Осуществляет перекрытие идентификатора: следующий за знаком & идентификатор считается определенным в программе, даже если он не совпадает с зарезервированным словом. Например:
Var
Ch: Byte;
……
mov ch, 0 |
{Посылаем 0 |
в регистр CH} |
mov &Ch, 0 |
{Посылаем 0 |
в переменную Ch} |
Операция ( )
Круглые скобки используются обычным для Паскаля образом – для изменения порядка исчисления выражения (подвыражение, ограни- ченное скобками, вычисляется в первую очередь). Если перед скоб- ками стоит имя типа, все выражение приобретает указанный тип. Например:
mov ах, ( (1+2)*3+4)*5 |
{АХ = 65} |
mov bx,1+2*3+4*5 |
{ВХ = 27} |
Операция [ ]
Определяет ссылку на память. Выражение внутри скобок вычисля- ется в первую очередь. Обычно оно связывается с регистрами BX, BP, SI, DI и может использовать операции + и – для указания индек- сации. Например:
Встроенный ассемблер |
351 |
|
|
Function SwapfX: Integer): Integer; |
{Меняет местами байты в слове X} |
begin |
|
asm |
|
mov ax, X |
|
mov BYTE PTR @Result, ah |
|
mov BYTE PTR @Result+l, al |
|
end; |
|
end; |
|
Операции * и /
* – умножение, / – целочисленное деление. Оба выражения должны иметь непосредственные абсолютные значения, такое же значение имеет и результатоперации. Например:
mov ах, 2*2 |
{АХ = 4} |
mov ах, 17/3 |
{АХ = 5} |
|
Операция MOD |
Возвращает остаток от целочисленного деления. Оба выражения должны иметь непосредственные абсолютные значения, такое же значение имеет и результатоперации. Например:
mov ax, 17 mod 3 |
{AX = 2} |
|
Операции SHL и SHR |
Осуществляют логический сдвиг влево (SHL) или вправо (SHR) вы- ражения, стоящего до операции, на количество разрядов, опреде- ляемое выражением после операции. Оба выражения должны иметь непосредственные абсолютные значения, такое же значение имеет и результатоперации. Например:
mov ah, 1 shl 7 |
{Ah = $80 = 128} |
|
Бинарная операция + |
Осуществляет сложение двух выражений. Выражения могут быть непосредственными значениями или ссылками на память, но только одно из них может быть перемещаемым. Если одно из выражений – ссылка на память, результат также определяет ссылку на память, а если одно из выражений – перемещаемое, результат будет переме- щаемым.
Бинарная операция –
Вычитание двух выражений. Первое выражение может быть любо- го класса, а второе должно быть абсолютным непосредственным