Программы и подпрограммы. связь по управлению и по данным
В целях структуризации программ, облегчения их разработки, отладки и понимания большие программы принято разбивать на отдельные модули, логически связанные друг с другом и достаточно автономные. Идея структурного программирования заключается в том, что структура программы должна отражать структуру решаемой задачи, чтобы алгоритм решения был ясно виден из исходного текста. С этой целью было введено понятие подпрограммы – набора операторов, выполняющих нужное действие и не зависящих от других частей исходного кода. Обычно критическим порогом размера подпрограммы, необходимого для быстрого понимания цели подпрограммы, считается 50 операторов. Возможность применения подпрограмм относит язык программирования к классу процедурных языков. Наличие подпрограмм позволяет вести проектирование приложения сверху вниз, решая сначала глобальные задачи, а потом детализируя каждую из них. Подпрограммы бывают двух типов – процедуры и функции. Процедура выполняет некоторую группу операторов, а функция вдобавок вычисляет некоторое значение и возвращает его в главную программу. В неё же возвращается и поток управления командами программы, причем подпрограмма должна уметь вернуть управление независимо от того, откуда она была вызвана. Вызов подпрограмм может быть вложенным. Чтобы работа программы имела смысл, ей надо получить данные из внешней (вызывающей) программы. Данные передаются в виде параметров или аргументов в виде списка, метод доступа к которому стандартизован и имеет аппаратную поддержку. В микропроцессорах INTELтакой поддержкой является аппаратный стек и команды работы с ним. Подпрограмма может иметь свои собственные локальные переменные, существующие только в интервале времени от входа в подпрограмму до выхода из нее, а также разделять с другими подпрограммами и главной программой доступ к глобальным переменным. Процесс взаимодействия вызывающей программы и вызываемой подпрограммы состоит из ряда последовательных этапов по следующему протоколу: Вызывающая программа: · Подготовить список параметров согласно соглашениям о связях; · Подготовить для подпрограммы адрес возврата; · Передать управление в подпрограмму. Вызываемая подпрограмма: · Сохранить состояние среды (контекст) вызывающей программы (в некоторых реализациях это действие выполняет операционная система); · Выделить память для локальных переменных; · Получить доступ к параметрам; · Выполнить алгоритм, заложенный в подпрограмму; при необходимости воспользоваться списком параметров, правильно извлекая и изменяя из значения в соответствии с соглашениями о связях; · Освободить память локальных переменных и восстановить контекст вызывавшей программы; · Возвратить управление в вызывавшую программу; Вызывающая программа: · Воспользоваться результатами работы подпрограммы.
Параметры, передаваемые в подпрограмму в момент её вызова, называются фактическими. Они замещают формальные параметры, указываемые в заголовке подпрограммы. Параметры могут передаваться по адресу (по имени) или по значению. Последние не могут изменить свои значения в вызывающей программе. По адресу передаются изменяемые параметры, а также массивы и структуры. Подпрограммы бывают реентерабельные (или повторновходовые) – это те, которые допускают вызов какой-либо собственной функции изнутри себя самой. Для их написания необходимо соблюдать некоторые правила, например, не использовать локальные переменные. Рекурсивные подпрограммы позволяют делать вызов себя из себя самой (классический пример – рекурсивное определение факториала). Реализация описанных понятий происходит по-разному в зависимости от архитектуры аппаратных средств и операционной системы. Для микропроцессоров INTELтрадиционным является использование аппаратного стека. Структура информации, соответствующая описанному выше протоколу, дана на следующем рисунке. Она образует «фрейм», или «кадр» стека. Следует помнить, что логический рост стека на данных микропроцессорах происходит «сверху вниз», от больших адресов к меньшим.
Рис. 1. Структура фрейма вызова подпрограммы
Перед вызовом подпрограммы вызывающая программа записывает адреса или значения параметров в стек. Вызов программы выполняется командой CALL, которая в зависимости от формата вызова (ближний или дальний), помещает в стек адрес возврата в виде регистра IP или пары регистров CS/IP. Вызванная подпрограмма должна сохранить в стеке все регистры, которые она будет использовать и модифицировать, а перед выходом восстановить их. Вызывающая программа после возврата к ней должна освободить место в стеке, занятое списком параметров. Подпрограмма при своей работе извлекает параметры из стека, пользуясь косвенной адресацией с помощью регистра BP. Если параметр передан по адресу, то этот адрес обычно переносится в регистр BX, и доступ к параметру также осуществляется с помощью косвенной адресации. Ниже приводится пример, в котором подпрограмма находит сумму элементов массива. Параметр n – число элементов в массиве – передаётся по значению, а адрес массива и результат в виде суммы – по адресу. Распределение параметров в фрейме подпрограммы смотрите в следующей таблице:
структура фрейма стека
; пример программы с подпрограммой assume cs:mycode,ds:mydate,ss:mystack mycode segment para start: push ds xor ax,ax push ax mov ax,seg mydate mov ds,ax ; подготовка списка параметров mov ax,n push ax lea ax,x push ax lea ax,sum push ax call sumarray ; освобождение стека от параметров pop ax pop ax pop ax ; возврат из главной программы retf ; подпрограмма sumarray: ; сохранение регистров push bp ; используется при вложенных вызовах mov bp,sp push ax push bx push cx push dx push si mov cx,[bp+8] ; значение n xor si,si ; обнуление индекса mov dx,si ; обнуление суммы в регистре dx mov bx,[bp+6] ; базовый адрес массива ; начало цикла cycl: mov ax,[bx][2*si] ; выборка элемента массива add dx,ax ; сложение c временной суммой inc si loop cycl ; завершение цикла mov bx,[bp+4] ; адрес sum mov [bx],dx ; и запись в память результата ; восстановление регистров и возврат pop si pop dx pop cx pop bx pop ax pop bp retn mycode ends mydate segment para n dw 7 x dw 5,4,-3,2,8,9,-6 sum dw 0 mydate ends mystack segment para stack ‘stack’ dw 100 dup (?) mystack ends end start
Популярное: Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (547)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |