Директивы ассемблера
Встроенный ассемблер не поддерживает никакие директивы, обычно используемые в других ассемблерах, за исключением DB, DW, DD. Структура директив такова:
Dx <константа> [,<константа>,…,<константа>]
Здесь:
- Dx – DB, DW или DD;
- <константа> – ассемблерная константа или константное выражение.
DB определяет цепочку байт, DW – слов, DD – двойных слов. Например:
db 'Турбо Паскаль',13.10 dw 0,$ FFFF, NearProc dd 'ABCD1.999999999, FarProc
В качестве константных выражений разрешается использовать любые ассемблерные константы со значением, не выходящим из диапазона байта (DB), слова (DW) или двойного слова (DD). В любой директиве можно определять строковую константу, которая приводит к побайтовому заполнению памяти ASCII-кодами символов. Поскольку слово (двойное слово) размещается в памяти, начиная со своего младшего байта, старший (старшие) байт в директивах DW и DD при размещении строкой константы может остаться неопределенным и заполняется нулем. Например, два следующих объявления эквивалентны:
dw '5' dw $35 {$35 – ASCII-код символа '5'}
В директивах DW и DD разрешается также указывать имена, которые в этом случае интерпретируются как адреса соответствующих объектов, причем для DW это – ближний адрес (смещение), а для DD – дальний. Например:
dw X {Размещает смещение переменной X} dd Proc {Размещает FAR-адрес процедуры Рrос}
Данные, определяемые директивами Dx, всегда размещаются в текущем кодовом сегменте. Разместить таким образом данные в сегменте данных (т.е. определить константу или типизированную константу) невозможно – для этого используются стандартные средства Турбо Паскаля. Более того, директивы не могут снабжаться именами, а поэтому использовать размещаемые с их помощью данные не так-то просто. В следующем примере на экран выводится текстовое сообщение. Для этого используется функция 9 вызова ДОС, в соответствии с которой в регистрах DS:DX должен содержаться адрес текстовой строки, а сама строка должна заканчиваться символом "$":
asm jmp ©NextCode {Обходим фрагмент данных} @: db 'Текстовая строка,13.10,'$' @NextCode: push ds {Сохраняем DS} push cs pop ds {DS = CS} mov dx,OFFSET @ {DS:DX – адрес строки} mov ah,9 {AH – код функции вывода} int 21h {Выводим строку} pop ds {Восстанавливаем DS} end;
Обратите внимание на использование регистра DS. В соответствии с требованиями функции 9, он должен содержать сегмент выводимой строки. В нашем случае строка располагается в кодовом сегменте, поэтому мы вынуждены сначала сохранить значение DS в стеке, а затем восстановить его. Если бы мы этого не сделали, по завершении ассемблерного оператора регистр DS указывал бы на сегмент кода и была бы потеряна связь программы Турбо Паскаля с глобальными переменными и константами.