Есть еще одна возможность организации данных Pascal - ассемблер - использование операндов директивы model. Вы помните, что она позволяет задать модель памяти и учесть соглашения языков высокого уровня о вызове процедур. Для связи Pascal - ассемблер ее можно задавать в виде:
MODEL large, pascal
Задание в таком виде директивы model позволяет
hописать аргументы процедуры непосредственно в директиве ргос:
asmproc ргос near ch:byte,x:word,y:word,kol:word
hавтоматически сгенерировать код пролога и эпилога в процедуре на ассемблере;
hдля доступа к аргументам, объявленным в ргос, использовать их имена. В этом отношении данный вариант является аналогом предыдущего варианта с директивой arg.
Листинг 4 демонстрирует, как отразились особенности данного варианта на тексте процедуры ассемблера. Обратите внимание, что пролога уже нет, так как он формируется транслятором автоматически; вместо эпилога обязательно нужно задавать только ret без операндов. Интересно изучить текст листинга 5, который получится в результате трансляции листинга 6. В нем видны сформированные транслятором коды пролога и эпилога. Кроме того, транслятор заместил команду ret без операндов командой ret 0008, которая, в соответствии с требованиями к взаимодействию с программами на Pascal, удалит из стека аргументы, переданные вызываемой процедуре.
Использование директивы MODEL (листинг 4).
prg4.pas
{Программа на Pascal, вызывающая процедуру на ассемблере, полностью совпадает с листингом 1}
;prg4.asm
MASM
MODEL large, pascal
STACK 256
.code
main:
asmproc proc near chr:BYTE,x:WORD,y:WORD,kol:WORD
PUBLIC asmproc
mov dh, byte ptr y ; y в dh
mov dl, byte ptr x ; x в dl
mov ah, 02h ; номер службы BIOS
int 10h ; вызов прерывания BIOS
mov ah, 09h ; номер службы BIOS
mov al, chr ; символ - в al
mov bl, 07h ; маска вывода символа
xor bh, bh
mov cx, kol ; kol в cx
int 10h ; вызов прерывания BIOS
ret
asmproc end ; конец процедуры
end main ; конец программы
Результат трансляции листинга 4 (листинг 5).
1 prg5.asm
2 MASM
3 0000 MODEL large,pascal
4 0000 STACK 256
5 0000 .code
6 0000 main:
7 0000 asmproc proc near chr:BYTE,x:WORD,y:WORD,kol:WORD
8 PUBLIC asmproc
1 9 0000 55 PUSH BP
1 10 0001 8В EC MOV BP, SP
1 11 0003 8А 76 06 mov dh, byte ptr у ;y в dh
12 0006 8А 56 08 mov dl, byte ptr x ;х в d1
13 0009 В4 02 mov ah, 02h ; номер службы BIOS
14 OOOB CD 10 int lOh ;вызов прерывания BIOS
15 OOOD B4 09 mov ah,09h ;номер службы BIOS
16 OOOF 8A 46 OA mov a1chr ;символ - в а1
17 0012 ВЗ 07 mov bl, 07h ;маска вывода символа
18 0014 32 FF xor bh, bh
19 0016 8В 4Е 04 mov cx.kol ;ko1 в сх
20 0019 CD 10 int lOh ;вызов прерывания BIOS.
1 21 001В 5D POP BP
1 22 001С С2 0008 RET 00008h
23 001F asmproc endp ;конец.процедуры
24 end main ;конец программы
Таким образом, можно считать, что мы разобрались со стандартными способами вызова ассемблерных процедур из программ на Pascal и передачи им аргументов. Эти способы будут работать всегда, но компилятор может предоставлять и более удобные средства. Их мы рассматривать не будем, так как читатель, наверное, уже понимает, что они будут сводиться, в конечном счете, к разобранной нами процедуре. Остались открытыми два вопроса:
1. Как быть с передачей данных остальных типов Pascal - ведь мы рассмотрели только данные размером в байт и слово?