12.3. Использование директивы ASSEMBLER
Если ту или иную подпрограмму нужно полностью написать на языке ассемблера, используя встроенный ассемблер, можно вместо операторных скобок asm...end использовать директиву assembler, которая имеет ряд особенностей.
Во-первых, все передаваемые параметры, размером отличные от 1, 2 или 4 байт, передаются всегда своим адресом без создания копии в стеке.
Во-вторых, нельзя использовать для передачи результата функции переменную @Result. Результат передается точно так же, как и при использовании TASM (см. п. 12.1). Исключение составляет результат типа string. В этом случае в переменной @Result находится адрес строки, в которую следует поместить полученную информацию.
В-третьих, для процедур и функций, не имеющих формальных и локальных параметров, вообще не выделяется область стека.
В-четвертых, так же как и в предыдущем случае, автоматически оформляется начало и конец подпрограммы, связанные с сохранением регистра ВР и освобождением стека от передаваемых параметров.
Ниже приведен пример использования такой директивы.
Пример. Программа, использующая подпрограмму-функцию, определяющую максимальный элемент из массива целых чисел и написанную на языке ассемблера, но использующую встроенный ассемблер и директиву assembler.
program EXAMPLE23; |
|
const |
|
N = 7 |
{Размер массива} |
Massiv : array[1..n] of Integer = (1, 2, 3, 2, 17, 7, 2); |
{Исходный массив} |
function Max (var Mas; N : Integer) : Integer; |
|
begin |
|
asm |
|
LDS SI, Mas |
{адрес массива} |
XOR AX, AX |
{0 - в регистр AX} |
MOV BX,8001h |
{минимальное целое число} |
MOV CX,N |
{число элементов массива} |
CMP CX,AX |
{сравнение с 0} |
JLE @@3 |
{0 или отрицательное число} |
@@1: LODSW |
{загрузка элемента массива} |
CMP AX, BX |
{сравнение с текущим максимумом} |
JLE @@2 |
{не больше} |
MOV BX,AX |
{новое максимальное число} |
@@2: LOOP @@1 |
{цикл} |
@@3: MOV AX,BX |
{результат функции} |
end |
|
end; |
|
begin |
|
WriteLn (' Максимальное число массива равно : ' , Max(Massiv, N)); |
|
ReadLn |
|
end. |
|
|