Энциклопедия 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.