Встроенный ассемблер позволяет в выражениях ассемблера полу-
чить доступ ко всем идентификаторам Паскаля, включая метки, конс-
танты, типы, переменные, процедуры и функции. Кроме того, во
встроенном ассемблере реализованы следующие специальные идентифи-
каторы:
@Code @Data @Result
Идентификаторы @Code и @Data представляют текущие сегменты
кода и данных соответственно. Их следует использовать только в
сочетании с операцией SEG:
asm
mov ax,SEG @Data
mov ds,ax
end;
Идентификатор @Result в операторной части функции переменную
- результат функции. Например, в функции:
function Sum(X, Y: Integer): Integer;
begin
Sum := X + Y;
end;
в операторе, присваивающем результат функции переменной Sum, мож-
но было бы при записи на встроенном ассемблере использовать пере-
менную @Result:
function Sum(X, Y: Integer): Integer;
begin
asm
mov ax,X
add ax,Y
mov @Result,ax
end;
end;
В выражениях встроенного ассемблера нельзя использовать сле-
дующие идентификаторы:
- стандартные процедуры и функции (например, WriteLn, Chr);
- специальные массивы Mem, MemW, MemL, Port, PortW;
- строки, значения с плавающей точкой и константы множест-
венного типа;
- метки, которые не описаны в текущем блоке;
- идентификатор @Result вне функции.
В Таблице 24.3 приведены значение, класс и тип различного
вида идентификаторов, которые можно использовать в выражениях
встроенного ассемблера (классы и типы выражений описываются в
следующем разделе):
Значения, классы и типы идентификаторов Таблица 24.3
─────────────┬────────────────────┬────────────────┬────────────┐
│Идентификат.│ Значение │ Класс │ Тип │
├────────────┼────────────────────┼────────────────┼────────────┤
│ Метка │ Адрес метки │ Память │ SHORT │
│ Константа │ Значение константы │ Непосредствен- │ 0 │
│ │ │ ный │ │
│ Тип │ 0 │ Память │ Размер типа│
│ Поле │ Смещение поля │ Память │ Размер типа│
│ Переменная │ Адрес переменной │ Память │ Размер типа│
│ Процедура │ Адрес процедуры │ Память │ NEAR / FAR│
│ Функция │ Адрес функции │ Память │ NEAR / FAR│
│ Модуль │ 0 │ Непосредствен- │ 0 │
│ │ │ ный │ │
│ @Code │ Адрес сегмента кода│ Память │ 0FFF0H │
│ @Data │ Адрес сегмента │ Память │ 0FFF0H │
│ │ данных │ │ │
│ @Result │ Смещение перемен- │ Память │ Размер типа│
│ │ ной результата │ │ │
└────────────┴────────────────────┴────────────────┴────────────┘
Локальные переменные (переменные, описанные в процедурах и
Функциях) всегда распределяются в стеке и доступны относительно
SS:BP, а значение идентификатора локальной переменной представля-
ет собой ее смещение со знаком от SS:BP. ассемблер автоматически
добавляет [BP] к ссылкам на локальные переменные. Например, с
учетом описаний:
procedure Test;
var
Count: Integer;
инструкции:
asm
mov ax,Count
end;
ассемблируются в MOV AX,[BP-2].
Встроенный ассемблер всегда интерпретирует параметр-перемен-
ную, как 32-разрядный указатель, а размер параметра-переменной
всегда равен 4 (размеру 32-разрядного указателя). В Паскале син-
таксис для доступа к параметру-переменной и к значению параметра
одинаков. В случае встроенного ассемблера это не так. Поэтому для
доступа к содержимому параметра-переменной вам сначала придется
загрузить 32-разрядный указатель, а затем обратиться к ячейке, на
которую он указывает. Например, если X и Y - параметры-переменные
приведенной выше функции Sum, то она может выглядеть следующим
образом:
function Sum(var X, Y: Integer): Integer;
begin
asm
les bx,X
mov ax,es:[bx]
les bx,Y
add ax,es:[bx]
mov @Result,ax
end;
end;
Некоторые идентификаторы, такие, как переменные типа запись,
имеют область действия, позволяющую обращаться к ним с помощью
операции выбора элементы структуры - точки (.). Например, с уче-
том описаний:
type
Point = record
X, Y: Integer;
end;
Rect = record
A, B: Point;
end;
var
P: Point;
R: Rect;
для доступа к полям в переменных P и R можно использовать следую-
щие конструкции:
asm
mov ax,P.X
mov dx,P.Y
mov cx,R.A.X
mov bx,R.B.Y
end;
Для непосредственного построения переменной можно использо-
вать идентификатор типа. Каждая из приведенных ниже инструкций
генерирует один и тот же машинный код, загружающий в AX
ES:[DI+4]:
asm
mov ax,(Rect PTR es:[di]).B.X
mov ax,Rect(es:[di].B.X
mov ax,es:Rect[di].B.X
mov ax,Rect[es:di].B.X
mov ax,es:[di].Rect.B.X
end;
Область действия задается типов, полем и идентификатором пе-
ременной типа записи или объектного типа. Кроме того, идентифика-
тор модуля открывает область действия конкретного модуля (как
полностью уточненный идентификатор в Паскале).