12.2. Использование встроенного ассемблера
Начиная с версии 6.0 Turbo Pascal содержит встроенный ассемблер, позволяющий писать отдельные части программ на языке ассемблера. Встроенный ассемблер обладает многими возможностями языка Turbo assembler, но приспособлен к использованию в программах, написанных на языке Паскаль (позволяет использовать идентификаторы программы, написанные на языке Паскаль, комментарии, имеющие такой же вид, как в языке Паскаль, позволяет воспользоваться встроенным отладчиком для пошагового выполения программы, контроля содержимого регистров и параметров программы и т. д.).
Так же как и Turbo assembler, встроенный ассемблер предполагает использование ряда предопределенных стандартных идентификаторов, имеющих специальное назначение. Если в программе будет введен идентификатор с таким же именем, но имеющий другое назначение, в частях программы, написанных на встроенном ассемблере, будет отдано предпочтение стандартному назначению этого идентификатора. Перечень стандартных идентификаторов встроенного ассемблера приведен в приложении В.
Наряду с возможностью использования идентификаторов языка Паскаль встроенный ассемблер использует три дополнительных идентификатора:
@Code - текущий кодовый сегмент (используется только с оператором SEG);
@Data - текущий сегмент данных (используется только с оператором SEG);
@Result - результат, полученный функцией (можно использовать только внутри функции).
При использовании встроенного ассемблера нельзя использовать:
- стандартные процедуры и функции;
- специальные массивы Mem, MemW, MemL, Port и PortW (см. п. 13);
- константы типа string, вещественных типов и типа-множества;
- процедуры и функции, объявленные с директивой inline;
- метки, объявленные не в данном блоке.
Часть программы, написанная на языке ассемблера, помещается в операторные скобки asm...end.
В следующем примере приведена программа, выполняющая те же функции, что и предыдущие программы, но использующая встроенный ассемблер.
Пример. Программа, использующая подпрограмму-функцию, определяющую максимальный элемент из массива целых чисел и написанную на языке ассемблера, но использующую встроенный ассемблер.
Program EXAMPLEE22; |
|
const |
|
N = 7 |
{Размер массива} |
Massiv : array[1..n] of Integer = (1, 2, 3, 2, 17, 7, 2); |
{Исходный массив} |
function Max (var Mas; N : Integer) : Integer; |
|
begin |
|
asm |
|
LDS SI, Mas |
{адрес массива} |
XOR AX, AX |
{0 - в регистр AX} |
MOV BX,8001h |
{минимальное целое число} |
MOV CX,N |
{число элементов массива} |
CMP CX,AX |
{сравнение с 0} |
JLE @@3 |
{0 или отрицательное число} |
@@1: LODSW |
{загрузка элемента массива} |
CMP AX, BX |
{сравнение с текущим максимумом} |
JLE @@2 |
{не больше} |
MOV BX,AX |
{новое максимальное число} |
@@2: LOOP @@1 |
{цикл} |
@@3: MOV @Result,BX |
{результат функции} |
end |
|
end; |
|
begin |
|
WriteLn (' Максимальное число массива равно : ' , Max(Massiv, N)); |
|
ReadLn |
|
end. |
|
Следует заметить, что при использовании встроенного ассемблера комментарии пишутся таким же образом, как и в языке Паскаль (в фигурных скобках). Назначение же точки с запятой несколько другое - этим знаком отделяются друг от друга команды, написанные на одной строке (такая возможность при использовании встроенного ассемблера существует), например:
LDS SI, Mas; XOR AX,AX; MOV BX,8001h
Как видно из примера, можно использовать идентификаторы, объявленные на языке Паскаль (параметры Mas, N). Нет необходимости сохранять и восстанавливать регистр ВР, удалять из стека передаваемые параметры, включая и локальные, и т. д.
|