Спецификация встроенного ассемблера
Приведенное выше общее описание архитектуры МП 8086/8088 является базовым для любого ассемблера, в том числе и для встроенного ассемблера Турбо Паскаля. Однако ассемблеры содержат массу дополнительных возможностей, облегчающих разработку готовых к работе программ. Эти возможности отражаются в директивах и макрокомандах ассемблера. Встроенный ассемблер не предназначен для написания законченных программ, поэтому в нем отсутствуют макрокоманды и директивы. Главной особенностью встроенного ассемблера является практически полное отсутствие в нем средств описания переменных и данных, т.к. эти объекты описываются средствами Турбо Паскаля.
Оператор ASM
Зарезервированное слово ASM открывает доступ к средствам встроенного ассемблера. Этот оператор может располагаться только внутри исполняемой части программы (подпрограммы). Область действия оператора ASM ограничивается ближайшим по тексту зарезервированным словом END. Таким образом, структура любого ассемблерного оператора такова:
asm
<Одна или несколько команд встроенного ассемблера>
end;
С точки зрения Турбо Паскаля пара asm... end считается операторными скобками, ограничивающими единственный оператор Паскаля, например:
if X>10 then
asm
.......
end
else
.......;
for k :=1 to 5 do
asm
.......
end;
Тело ассемблерного оператора asm... end может быть пустым или содержать несколько ассемблерных команд. Каждая ассемблерная команда должна располагаться на отдельной строке или отделяться от следующей за ней команды символом «;». Ниже приводятся два разных способа написания одной и той же последовательности ассемблерных команд:
asm
mov ah,0; int $16; mov ChCode, al; mov ScCode, ah
end;
asm
mov ah , 0
int $16
mov ChCode, al
mov ScCode, ah
end;
В конце строки, содержащей единственную ассемблерную команду, или между двумя командами, располагающимися на одной строке, разрешается вставлять комментарий, который должен оформляться по обычным правилам Турбо Паскаля, т.е. ограничиваться символами «{», «}» или «(*», «*)». Таким образом, комментарии разрешены между ассемблерными командами, но не внутри них. Например, такой оператор будет правильным:
asm
{Инициируем регистры}
lea si,X; push ds;
pop es; {ES := DS}
lea di,Y; mov ex,100
cld {Перенос - вперед}
rep {Выполняем Y := X}
movsw
{Здесь нет ошибки - комментарий можно вставлять между префиксом и командой}
end;
а такой - неправильным:
asm
{Готовим регистры}
lea si,X; push ds;
pop {ES:=DS} es;
{Ошибка! Комментарий разорвал мнемонику команды и ее операнд}
lea di,Y; mov ex,100 {и направление} eld
{Комментарий является разделителем команд, поэтому перед ним можно не ставить ";"}.
rep movsw
end;
В пределах ассемблерного оператора допускаются любые команды, но Турбо Паскаль требует выполнения следующего соглашения:
В начале ассемблерного оператора регистр DS содержит сегмент кода, SS - сегмент стека, ВР - текущий стек, SP указывает на вершину стека. Все эти регистры должны иметь точно такие же значения к моменту завершения работы ассемблерного оператора.
Программист не должен делать каких-либо предположений о содержимом остальных регистров, и эти регистры могут иметь произвольное значение после завершения работы ассемблерного оператора. Исключением является случай ассемблерной функции, которая должна использовать некоторые регистры для возврата своего значения (см. п. 12.2.3).