Использование turbo pascal с языком ассемблера. Встроенный ассемблер, страница 6

Таблица 22.1  суммирует значение,  класс и тип различных видов символов, которые могут  использоваться  в  выражениях  встроенного

Ассемблера (типы и классы выражений описаны в следующем разделе).

Таблица 22.1. Значения, классы и типы символов.

------------------------------------------------------------------Символ         Значение           Класс            Тип

------------------------------------------------------------------Метка        Адрес метки         Память            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]

Встроенный Ассемблер всегда интерпретирует var параметр как 32

-битный указатель  и  размер  var  параметра   всегда   4   (размер

32-битного указателя).  В  Паскале  синтаксис  для  доступа  к  var

параметру и параметру  значению  одинаков.  Не  так  во  встроенном

Ассемблере. Поскольку  var  параметры в действительности указатели,

Вы должны интерпретировать их так во  встроенном  Ассемблере.  Так, чтобы обратиться к содержимому var параметра, Вы вначале загружаете

32-битный указатель,  а затем обращаетесь к памяти,  на которую  он указывает. Например, если X и Y - var параметры функции 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;

Идентификатор типа можно использовать для  создания переменных

"на лету".   Каждая   инструкция   ниже  генерирует  машинный  код, загружающий содержимое ES:[DI+4] в AX.

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;

Сфера действия символа  типа  поля  или  записи  -  это  сфера действия записи или объекта этого типа.  Кроме того,  идентификатор модуля открывает сферу действия определенного модуля  так  же,  как полный квалифицированный идентификатор в Паскале.

Классы выражений.

Встроенный Ассемблер делит выражения на  3  класса:  регистры, ссылки на память и непосредственные значения.

Выражение, которое  состоит  только  из  имени  регистра - это регистровое выражение.  Пример регистрового выражения - это AX, CL,

DI и  ES.  Используемые  как операнды,  регистровые выражения прямо ассемблируются в  инструкции,  которые  воздействуют  на   регистры процессора.