|
Директивы ассемблера
Встроенный ассемблер
не поддерживает никакие директивы, обычно используемые
в других ассемблерах, за исключением 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 указывал бы на сегмент кода и была
бы потеряна связь программы Турбо Паскаля с глобальными
переменными и константами.
|