function StringOf; external;
end.
Программа на Ассемблере, реализующая функции UpperCase и
StringOf, показана ниже. Она должна быть ассемблирована в файл
Strs.OBJ до компиляции модуля Strings. Заметим, что программы используют дальнюю модель вызова, так как они объявлены в интерфейсной части модуля.
CODE SEGMENT BYTE PUBLIC
ASSUME CS:CODE
PUBLIC UpperCase, StringOf ; объявление функций
; function UpperCase(S: String): String;
UpperRes EQU DWORD PTR [BP+10]
UpperStr EQU DWORD PTR [BP+6]
UpperCase PROC FAR
push bp ; сохранить bp
mov bp,sp ; установить стек
push ds ; сохранить ds
lds si,UpperStr ; загрузить адрес строки
les di,UpperRes ; загрузить адрес результата
cld
lodsb ; загрузить длину строки
stosb ; копировать в результат
mov cl,al ; длину строки в CX
xor ch,ch
jcxz U3 ; пропустить, если строка пустая
U1: lodsb ; загрузить символ
cmp al,'a' ; пропустить если не 'a'..'z'
jb U2
cmp al,'z'
ja U2
sub al,'a'-'a' ; преобразовать в заглавные
U2: stosb ; запомнить в результат
loop U1 ; цикл для всех символов
U3: pop ds ; востановить ds
pop bp ; востановить bp
ret 4 ; удалить параметр и возврат
UpperCase ENDP
; procedure StringOf(var S :string; Ch : char; Count: byte)
StrOfs EQU DWORD PTR [BP + 10]
StrOfChar EQU BYTE PTR [BP + 8]
StrOfCount EQU BYTE PTR [BP + 6]
StringOf Proc FAR
push bp ; сохранить bp
mov bp,sp ; установить стек
les di,StrOfRes ; загрузить адрес результата
mov al,StrOfCount ; загрузить счетчик
cld
stosb ; сохранить длину
mov cl,al ; счетчик в CX
xor ch,ch
mov al, StrOfChar ; загрузить символ
rep STOSB ; сохранить строку символов
pop bp ; восстановить bp
ret 8 ; удалить параметр и возврат
StringOf ENDP
CODE ENDS
END
Для того чтобы ассемблировать пример и откомпилировать модуль, используйте команды:
TASM STRS
TPC strings
Следующий пример показывает, как программа на Ассемблере может обращаться к программам и переменным Паскаля. Программа Numbers
читает до 100 целых значений и затем вызывает процедуру на
Ассемблере, чтобы проверить диапазон каждого из этих значений. Если значение выходит из диапазона, процедура на Ассемблере вызывает процедуру на Паскале для его печати.
program Numbers;
{$L CHECK}
var
Buffer: array[1..100] of Integer;
Count: Integer;
procedure RangeError(N: Integer);
begin
WriteLn('Range error: ', N);
end;
procedure CheckRange(Min, Max: Integer); external;
begin
Count := 0;
while not EOF and (Count < 100) do
begin
Count := Count + 1;
ReadLn(Buffer[Count]);
{закончится, когда пользователь введет CTRL-Z или после 100 итераций}
end;
CheckRange(-10,10);
end.
Программа на Ассемблере, реализующая процедуру CheckRange, приведена ниже.
Она должна быть ассемблирована в файл Check.OBJ до компиляции программы Numbers. Заметим, что процедура использует ближнюю модель вызова, так как объявлена в программе.
DATA SEGMENT WORD PUBLIC
EXTRN Buffer: WORD, Count: WORD; ;Переменные Паскаля
DATA ENDS
CODE SEGMENT BYTE PUBLIC
ASSUME CS: CODE, DS: Buffer
EXTRN RangeError: NEAR ;реализован в Паскале
PUBLIC CheckRange ;реализован здесь
CheckRange PROC NEAR
mov bx,sp ;получить указатель параметров
mov ax,ss:[bx+4] ;загрузить Min
mov dx,ss:[bx+2] ;загрузить Max
xor bx,bx ;очистить индекс данных
mov cx,Count ;загрузить Count
jcxz SD4 ;пропустить если 0
SD1: cmp Buffer[BX],AX ;слишком мал?
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.