Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
BorlandPascal.doc
Скачиваний:
54
Добавлен:
17.03.2015
Размер:
2.83 Mб
Скачать

Процедуры и функции ассемблера

До сих пор мы рассматривали конструкцию asm...end, как опе-

ратор с обычной частью begin...end. Директива assembler в Borland

Pascal позволяет вам писать на встроенном ассемблере целиком про-

цедуры и функции без необходимости begin...end. Приведем пример

функции на ассемблере:

function LongMul(X, Y: Integer) : Longint; assembler;

asm

mov ax,X

imul Y

end;

Директива assembler приводит к тому, что Borland Pascal вы-

полняет при генерации кода следующую оптимизацию:

- Компилятор не генерирует код для копирования парамет-

ров-значений в локальные переменные. Это влияет на все па-

раметры-значения строкового типа и другие значения-пара-

метры, размер которых не равен 1, 2 или 4 байтам. Внутри

процедуры или функции такие параметры должны интерпретиро-

ваться, как если бы они были параметрами-переменными.

- Компилятор не выделяет память для результата функции, и

ссылка на идентификатор @Result будет ошибкой. Однако

строковые функции являются исключением из этого правила -

они всегда имеют указатель @Result, который распределяется

пользователем.

- Для процедур и функций, не имеющих параметров и локальных

переменных, компилятор не генерирует кадров стека.

- Для процедуры и функции на ассемблере автоматически гене-

рируется код выхода:

push bp ; присутствует, если Locals <> 0 или

; Params <> 0

mov bp,sp ; присутствует, если Locals <> 0 или

; Params <> 0

sub sp,Locals ; присутствует, если Locals <> 0

...

mov sp,bp ; присутствует, если Locals <> 0

pop bp ; присутствует, если Locals <> 0 или

; Params <> 0

ret Params ; всегда присутствует

где Locals - размер локальных переменных, а Params - раз-

мер параметров. Если и Locals и Params = 0, то кода входа

не будет, и код выхода состоит просто из инструкции RET.

Функции, использующие директиву assembler, должны возвращать

результат следующим образом:

- результаты функции порядкового типа (Integer, Char,

Boolean, перечислимые типы) возвращаются в AL (8-разрядное

значение), AX (16-разрядное значение) или DX:AX (32-раз-

рядное значение);

- результаты функции вещественного типа (Real) возвращаются

в DX:BX:AX;

- результаты функции типов 8087 (Single, Double, Extended,

Comp) возвращаются в ST(0) (регистр стека сопроцессора

8087);

- результаты функции типа указатель возвращаются в DX:AX;

- результаты функции строкового типа возвращаются во времен-

ной ячейке, на которую указывает @Result.

Директива assembler во многом похожа на директиву external.

Процедуры и функции на ассемблере должны должны подчиняться тем

же правилам, что и процедуры и функции типа external. Следующие

примеры показывают некоторые отличия операторов asm в обычных

процедурах и функциях от процедур и функций ассемблера. В первом

примере оператор asm используется в обычной функции для преобра-

зования строки в верхний регистр. Заметим, что значение параметра

Str в этом случае ссылается на локальную переменную, поскольку

компилятор автоматически генерирует код входа, копирующий факти-

ческий параметр в локальную память.

function UpperCase(Str: String): String;

begin

asm

cld

lea si,Str

les di,@Result

SEGSS lodsb

stosb

xor ah,ah

xchg ax,cx

jcxz @3

@1:

SEGSS lodsb

cmp al,'a'

ja @2

cmp al,'a'

ja @2

cmp al,'z'

jb @2

sub al,20H

@2:

stosb

loop @1

@3:

end;

end;

Второй пример на ассемблере представляет собой версию функ-

ции UpperCase. В этом случае Str не копируется в локальную па-

мять, и функция должна интерпретировать Str, как параметр-пере-

менную.

function UpperCase(S: String): String; assembler;

asm

push ds

cld

lds si,Str

les di@Result

lodsb

stosb

xor ah,ah

xchg ax,cx

jcxz @3

@1:

lodsb

cmp al,'a'

ja @2

cmp al,'z'

jb @2

sub al,20H

@2:

stosb

loop @1

@3:

pop ds

end;

Соседние файлы в предмете Программирование на Pascal