Анимация
JavaScript
|
Главная Библионтека тельность - это просто команда "JMP МАХ100". Но в случае, когда необходимо передать аргументы, обычно необходима более длинная вызывающая последовательность. Например, программа 1.3.2М - это обобщенный вариант МАХ100; она находит максимум среди первых п элементов таблицы. Параметр п появляется в индексном регистре 1, и его последовательность вызова LD1 =п= ENT1 п JMP MAXIMUM JMP MAXIMUM включает два шага. Если последовательность вызова занимает с ячеек памяти, то формула (2) вычисления объема сэкономленного места принимает вид (т - 1) (/с - с) - constant, (3) а время, которое тратится на связь с подпрограммой, немного увеличивается. Может возникнуть необходимость внесения дальнейших корректив в приведенные формулы, если потребуется сохранить и восстановить некоторые регистры. Например, работая с подпрограммой МАХ100, следует помнить, что, записывая "JMP МАХ100", мы не только заносим максимальное значение в регистр А, а его позицию - в регистр 12, но и обнуляем регистр 13. Нужно иметь в виду, что подпрограмма может испортить содержимое регистров. Чтобы предотвратить изменение подпрограммой МАХ100 содержимого г13, необходимо включить дополнительные команды. Самый короткий и самый быстрый способ сделать это на MIX состоит в том, чтобы вставить команду "ST3 ЗР(0:2)" сразу после МАХ100 и команду "ЗН ENT3 *"- непосредственно перед EXIT. В итоге это выльется в две дополнительные строки кода плюс три машинных такта для каждого вызова подпрограммы. Подпрограмму можно рассматривать как расширение машинного языка компьютера. Внеся в память машины подпрограмму МАХ100, получим единственную команду (а именно- "JMP МАХ100"), которая находит максимум. Важно определить результат работы каждой подпрограммы так же тщательно, как были определены сами операторы машинного языка. Поэтому программист обязательно должен записать характеристики каждой подпрограммы, даже если больше никто не будет пользоваться этой программой или ее спецификацией. Например, подпрограмма MAXIMUM, приведенная в разделе 1.3.2, имеет следующие характеристики. Последовательность вызова: JMP MAXIMUM. Состояние при входе: гИ = п; в предположении, что п > 1. Состояние при выходе: г А = шах CONTENTS (X-Ь А:) = CONTENTS (X-- г12); l<fc<n rI3 = 0; содержимое rJ и CI также меняется. (Обычно мы не будем упоминать о том, что подпрограмма оказывает влияние на регистр J и флаг сравнения; здесь об этом говорится только для полноты.) Заметьте, что на гХ и гП подпрограмма действия не оказывает, в противном случае эти регистры были бы упомянуты в описании состояния при выходе. В спецификации должны также перечисляться все внешние для подпрограммы ячейки памяти, на которые она может оказать воздействие. В нашем случае спецификация позволяет заключить, что в памяти ничего не сохранялось, так как в (4) ничего не говорится об изменениях в памяти. А теперь давайте рассмотрим несколько входов в подпрограммы Предположим, существует программа, которой требуется общая подпрограмма MAXIMUM Но дело в том, что обычно используемся частный случай МАХ100, для которого п = 100. Эти две подпрограммы можно объединить следующим образом. МАХ100 ENT3 100 Первый вход MAXN STJ EXIT Второй вход JMP 2F Продолжать, как в (1) (5) EXIT JMP * Вернуться к основной программе Подпрограмма (5) практически такая же, как (1), только первые две команды поменялись местами. Здесь использовался тот факт, что команда "ENT3" не изменяет содержимое регистра J. Чтобы добавить к этой подпрограмме третий вход, МАХ50, в начало нужно вставить строки МАХ50 ENT3 50 JSJ MAXN . (Напоминаю, что "JSJ" означает переход без изменения регистра J.) Если число параметров невелико, то желательно передавать их в подпрограмму одним из двух способов- занеся их в подходящие регистры (аналогично тому, как мы использовали г13 для хранения параметра п в MAXN, а гП-для хранения параметра п в MAXIMUM) либо сохранив их в фиксированных ячейках памяти. Другой удобный способ передачи аргументов состоит в том, чтобы просто перечислить их после команды JMP. Подпрограмма сможет обратиться к своим параметрам, поскольку она знает содержимое регистра J. Например, если бы понадобилось создать для MAXN последовательность вызова JMP MAXN CON п , то подпрограмму можно было бы написать следующим образом: MAXN STJ *+1 ENTl * rll -t- rJ LD3 0,1 rI3 4-n JMP 2F Продолжать, как в (1) (8) JSP IB JMP 1,1 Возврат I Ha таких машинах, как IBM 360, на которых связь с подпрограммами обычно осуществляется путем помещения адреса ячейки возврата в индексный регистр, приведенный выше способ особенно удобен. Он используется также, когда у подпрограммы много аргументов либо если программа создана компилятором Метод нескольких входов, который использовался выше, в этом случае не подходит. Его можно "подделать", написав МАХ100 STJ IF JMP MAXN CON 100 IH JMP * , HO это выглядит уже не так привлекательно, как (5). Для подпрограмм с несколькими выходами обычно используется метод, аналогичный перечислению аргументов. Множественный выход означает, что подпрограмма возвращается в одно из нескольких различных мест в зависимости от условий, обнаруженных подпрограммой. В самом строгом смысле место, в которое возвращается подпрограмма после выхода, - это параметр. Поэтому, если существует несколько мест, в которые она может выйти в зависимости от обстоятельств, они должны быть предоставлены в качестве аргументов. В нашем завершающем примере в подпрограмме поиска максимума будет два входа и два выхода. Последовательность вызова имеет такой вид. Для произвольного п ENT3 п JMP MAXN Выйти здесь, если шах < О или шах > гХ. Выйти здесь, если О < шах < гХ. Для п = 100 JMP МАХ100 Выйти здесь, если max < О или шах > гХ Выйти здесь, если О < max < гХ. (Другими словами, выход производится на две ячейки ниже команды перехода, если максимум положителен и меньше значения, которое содержится в регистре X.) Для этих условий подпрограмму написать несложно. МАХ100 ENT3 100 Вход для п = 100 MAXN STJ EXIT Вход для проиэвачьного п JMP 2F Далее, как в (1) J3P IB JANP EXIT STX TEMP CMPA TEMP JGE EXIT ENT3 1 Выполнить нормальный выход, если max < О Выполнить нормальный выход, если max > гХ. В противном случае выйти через второй выход EXIT JMP *,3 Вернуться в нужное место Одни подпрограммы могут вызывать другие подпрограммы. В сложных программах вызовы подпрограмм, вложенных более чем на пять уровней, - это не такое уж редкое явление. Используя описанную выше связь подпрограмм, необходимо придерживаться единственного ограничения - одна подпрограмма не может вызывать другую подпрограмму, которая (прямо или косвенно) вызывает ее. Например, рассмотрим следующий сценарий. [Главная программа] JMP А [Подпрограмма А] А STJ EXITA JMP В EXITA JMP ♦ [Подпрограмма В] В STJ EXITB JMP С EXITB JMP * [Подпрограмма С] С STJ EXITC JMP А EXITC JMP ♦ (10) Если главная программа вызывает А, которая вызывает В, которая вызывает С, а затем С вызьшает А, то адрес в ячейке EXITA, по которому осуществляется выход 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 [ 70 ] 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |