Энциклопедия Turbo Pascal. Главы 1-4 - Создание внешней программы на ассемблере

ОГЛАВЛЕНИЕ

Создание внешней программы на ассемблере

Теперь, когда рассмотрены соглашения о связях,  приведем код действительной программы на ассемблере. Предположим, что требуется составить программу на ассемблере для следующей функции:

     function Xmul(a, b: integer): integer; begin
       a: = a*b;
       Xnul: = a;
     end;

Поскольку эта функция будет вызываться из программы на TURBO-Паскале,  то два аргумента целого типа будет помещаться в стек, занимая два слова. Поэтому при следующем вызове функции

     xmu(10,20);

первым будет помещаться в стек значение 20 и затем значение 10. Следует помнить, что для скалярных переменных значения по мещаются в стек. Для массива и записи в стек помещается адрес.

Результат этой функции будет помещен в регистр АХ. Ниже приводится код этой функции на ассемблере:

     code    segment 'code'
             assume cs:code
     public  xmul
     xmul    proc near

     ;сохранить указатель стека
             push bp
             mov bp,sp

     ;получить первый параметр
             mov ax,[bp]+4
     ;умножить на второй параметр
             mul word ptr [bp]+6
     ;восстановить "вр" и очистить стек
     ;результат уже находится в регистре АХ
             pop bp
             ret 4
     xmul    endp
     code    ends
             end

Следует отметить,  что все регистры сохраняются при помощи инструкций "push" и "рор" и доступ к  аргументам осуществляется через стек.  Кроме того,  функция "xmul" объявлена как "public". Это необходимо для обеспечения Турбо Паскалем ее правильной связи с остальной программой. Если вы незнакомы с ассемблером процессоров 8086 и 8088,  то вам могут помочь следующие пояснения.  Рассмотрим следующий код:

     mov  bp,sp
     mov  ax,[bp]+4.

Эти инструкции помещают адрес вершины стека в регистр ВР и затем сдвигают четвертый байт дальше в стек /т.е.  параметр "а" помещается в регистр АХ/.  Параметры занимают четвертый и шестой байты,  поскольку адрес возврата и инструкция "push bp" занимают четыре байта. Следовательно, параметры начинаются на четыре байта ниже вершины стека.

Внешняя функция "xmul" является "близкой"  процедурой.  Если процедура объявляется в программе или в разделе реализации блока, она должна объявляться с параметром "near".  Если внешняя функция объявляется в секции интерфейса блока, то она должна будет объявляться с параметром "far".

Перед использованием этой внешней функции она должна быть ассемблирована с применением макроассемблера фирмы "Майкроусофт". Следует помнить, что все процедуры, функции и переменные, к которым необходимо обеспечить доступ в вашей программе, должны объявляться с параметром "public".

В вашей программе на Турбо Паскале можно использовать указанную внешнюю функцию следующим образом:

     {программа,  которая обеспечивает связь с внешней подпрог
раммой, написанной на ассемблере}

     program asmtest;

     {SL XMUL}

     var
       a, b, c: integer;

     function xmul(x, y: integer): integer; external;

     begin
       a: = 40;
       b: = 20;
       c: = xmul(a,b); {умножение "а" на "в" и получение
                  результата}
       WriteLn(c);
     end.

Директива компилятора $L используется для указания на необходимость   подсоединения к  программе объектного кода модуля "xmul".

Следует помнить,  что все примеры даются для ассемблера процессоров 8086 и  8088.  Если используется Турбо Паскаль версии СР/М,  то примеры должны быть изменены в соответствии с руководством пользователя по Турбо Паскалю.  Кроме того, связь с подпрограммами на языке ассемблера будет отличаться для TURBOПаскаля версий более ранних, чем версия 4.0.