КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ. Подпрограмма, в зависимости от выполняемых ею функций, может требовать передачи из вызывающей программы определенных данных
Подпрограмма, в зависимости от выполняемых ею функций, может требовать передачи из вызывающей программы определенных данных, которые принято называть аргументами или параметрами и возвращать в вызывающую программу результат вычислений. Некоторые подпрограммы могут вообще не принимать никаких параметров и не возвращать результат. Чаще всего подпрограмма (процедура) оформляется так, как показано в следующем фрагменте кода: Листинг 7.1 mov AX, 0 mov BX, 0 jmpstart addlproc; точка входа в процедуру addl incAX ret; возврат в вызывающую программу addlendp sublproc; точка входа в процедуру subl decBX ret возврат в вызывающую программу subl endp start: call add1; вызовпроцедуры addl callsub1 вызовпроцедурыsubl jmpstart Как видно из приведенного фрагмента кода, в начале процедуры (перед первой выполняемой командой) должна находиться директива proc, а после последней выполняемой команды — директива endp. Процедура обязательно должна заканчиваться командой ret. В одном ассемблерном файле с расширением ASM можно размещать несколько процедур. Директива proc может принимать один из двух параметров: near или far. Параметр near указывает на то, что процедура является ближней, a far указывает на то, что процедура дальняя. Если параметр отсутствует, то считается, что процедура имеет тип near (поэтому параметр near обычно и не указывается). К ближней (near) процедуре можно обращаться только из того сегмента команд, где она объявлена, а к дальней (far) процедуре — из любых сегментов команд, включая тот, где она объявлена. Для 32-разрядных приложений все вызовы процедур считаются ближними. В момент вызова процедуры команда call помещает в стек адрес команды, следующей непосредственно за call, уменьшая значение указателя стека SP (ESP). Команда ret вызываемой процедуры использует этот адрес для возврата в вызывающую программу, автоматически увеличивая при этом указатель вершины стека. Типы адресации (near или far) команд ret и call должны соответствовать друг другу. Вызываемая процедура может вызвать с помощью команды call следующую процедуру и т. д., поэтому стек должен иметь достаточный размер для того, чтобы хранить в нем все записываемые данные. Команда call может иметь один из перечисленных ниже форматов вызова: • прямой ближний (в пределах текущего программного сегмента); • прямой дальний (вызов процедуры, расположенной в другом программном сегменте); • косвенный ближний (в пределах текущего программного сегмента с использованием переменной, содержащей адрес перехода); • косвенный дальний (вызов процедуры, расположенной в другом программном сегменте, с использованием переменной, содержащей адрес перехода). Листинг 7.2. Демонстрация дальних вызовов процедур (16-разрядная версия) .model large data segment s1 DB 0dh, 0ah, " Direct far call of subrl demo! $" s2 DB 0dh, 0ah, " Direct far call of subr2 demo! $" data ends code1 segment assume CS: code: mainproc; точка входа в основную программу mov AX, @data mov DS, AX call far ptr subrl; дальнийвызовподпрограммы subrl callfarptrsubr2; дальний вызов подпрограммы subr2 ; код команды call в обоих случаях ; 9А < смещение> < сегмент> movAH, lh int 21h mov Ax, 4C00h int 21h main endp code ends code2 segment assume CS: code2 subrlprocfar: объявлениедальнейподпрограммыsubrl lea DX, si mov AH, 9h int 21h ret; команда ret имеет код 0CBh (возврат из дальней ; подпрограммы) subrl endp subr2 proc far; объявление дальней подпрограммы subr2 lea dx, s2 mov AH, 9h int 21h ret; команда ret имеет код 0CBh (возврат из дальней : подпрограммы) subr2 endp code2 ends СОДЕРЖАНИЕ РАБОТЫ Отладить пример и убедитьсяв его работоспособности. ВОПРОСЫ ВЫХОДНОГО КОНТРОЛЯ 1. Назовите форматы вызова процедур. 2. Приведите пример оформления процедуры.
|