TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

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

             До сих пор мы рассматривали конструкцию 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;

Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz