Передача параметров при вызове подпрограмм
Вызывая подпрограмму, программа должна передать ей параметры (операнды), или же их адреса. Закончив свою работу, подпрограмма вернет другие параметры — результаты выполнения. Такой обмен информацией между вызывающей программой и подпрограммой называется передачей параметров. Передача параметров может выполняться несколькими способами. Например, параметры можно помещать в регистры или в оперативную память, откуда подпрограмма сможет их считать. В качестве альтернативы параметры можно поместить в стек, используемый для хранения адресов возврата.
Использование регистров ядра процессора — способ простой и эффективный. В таблице 17.2 показано, как реализовать программу, выполняющую сложение последовательности чисел, в виде подпрограммы с передачей параметров через регистры.
Таблица 17.2
Метка | Команда | Операнды | Комментарий | |
Вызывающая программа | ||||
Move | N, R1 | R1 играет роль счетчика | ||
Move | #NUM,R2 | R2 указывает на последовательность | ||
Call | LISTADD | Вызов подпрограммы | ||
Move | R0,SUM | Сохранение результата | ||
…….. | ||||
Подпрограмма | ||||
LISTADD LOOP | Clear | R0 | Инициализация суммы значением 0 | |
Add | (R2)+,R0 | Добавление числа из последовательности | ||
Decrement | R1 | Уменьшение счетчика | ||
Branch>0 | LOOP | Если счетчик не равен 0, возврат на цикл | ||
Return | Возврат в вызывающую программу | |||
Длина последовательности п, информация о которой хранится в оперативной памяти по адресу N, и адрес первого числа NUM1 передаются подпрограмме через регистры R1 и R2. Вычисленная подпрограммой сумма возвращается вызывающей программе через регистр R0. Первые две команды загружают в регистры R1 и R2 значения N и NUM1. Команда CALL выполняет переход к подпрограмме, начинающейся по адресу LISTADD. Кроме того, эта команда помещает в стек адрес возврата из подпрограммы. Подпрограмма вычисляет сумму и помещает ее в регистр R0. После возврата из подпрограммы вызывающая программа сохраняет эту сумму в оперативной памяти по адресу SUM.
Если у подпрограммы много параметров, для их передачи может просто не хватить регистров общего назначения. С другой стороны, стек — структура гибкая, в него можно поместить много параметров. Следующий пример показывает, как выполняется передача параметров через стек. В таблице 17.3приведена та же программа, выполняющая сложение последовательности чисел, но реализованная в виде подпрограммы LISTADD. Любая другая программа может вызвать указанную подпрограмму для сложения последовательности чисел. Подпрограмме LISTADD передается адрес первого числа в последовательности и количество ее элементов. Подпрограмма выполняет сложение и возвращает полученную сумму. Ее параметры помещаются в стек процессора, на который указывает регистр SP. Предположим, что до вызова подпрограммы вершина стека располагается на уровне 1 (рис.17.4). Вызывающая программа помещает в стек адрес NUM1 и значение п и вызывает подпрограмму LISTADD. Кроме того, команда CALL помещает в стек адрес возврата из подпрограммы. Теперь вершина стека располагается на уровне 2.
Таблица 17.3
Метка | Команда | Операнды | Комментарий | |
Предполагается, что вершина стека расположена на уровне 1 | ||||
Move | #NUM1,-(SP) | Помещение параметров в стек | ||
Move | N,-(SP) | |||
Call | LISTADD | Вызов подпрограммы ( вершина стека на уровне 2) | ||
Move | 4(SP),SUM | Сохранение результата | ||
Add | #8,SP | Восстановление вершины стека ( вершина стека на уровне 1) | ||
……. | ||||
LISTADD | MoveMultyple | R0-R2,-(SP) | Сохранение регистров ( вершина стека на уровне 3) | |
Move | 16(SP),R1 | Инициализация счетчика значением n | ||
Move | 20(SP),R2 | Инициализация указателя на последовательность чисел | ||
Clear | R0 | Инициализация суммы значением 0 | ||
LOOP | Add | (R2)+,R0 | Добавление числа из последовательности чисел | |
Decrement | R1 | Уменьшение счетчика | ||
Branch>0 | LOOP | Проверка цикла | ||
Move | R0,20(SP) | Помещение результата в стек | ||
MoveMultyple | (SP)+,R0-R2 | Восстановление регистров | ||
Return | Возврат в вызывающую программу | |||
Рис.17.4. Программа, выполняющая сложение последовательности чисел и реализованная как подпрограмма, с передачей параметров через стек
Подпрограмма использует три регистра. Поскольку в них могут содержаться данные, принадлежащие вызывающей программе, их содержимое сохраняется в стеке. Для помещения в стек содержимого регистров от R0 до R2 использована команда MoveMultiple. Подобные команды имеются у многих архитектур. Теперь вершина стека располагается на уровне 3. С помощью индексной адресации подпрограмма считывает из стека параметры п и NUM1. Значение указателя стека при этом не меняется, поскольку на вершине стека по-прежнему располагаются нужные элементы данных. Значение п загружается в регистр R1, который будет играть роль счетчика, а адрес NUM1 — в регистр R2, который будет служить указателем при сканировании списка значений. Регистр R0 должен содержать результат суммирования. Перед возвратом из подпрограммы содержимое регистра R0 помещается в стек, заменяя параметр NUM1, который больше не нужен. Затем из стека восстанавливается содержимое трех регистров, использовавшихся подпрограммой. Теперь верхним элементом стека является адрес возврата, расположенный на уровне 2. После возврата из подпрограммы вызывающая программа сохраняет результат в оперативной памяти по адресу SUM и возвращает вершину стека на ее исходный уровень, уменьшая значение SP на 8.
Дата добавления: 2015-09-29; просмотров: 1285;