Я прочитал в руководстве по MIPS, что при вызовах процедур сохраняются только регистры $ s0- $ s7.
Ничего волшебного не происходит с $s0
- $s7
при вызове (например, jal some_routine
просто вставляет адрес возврата в $ra
и переходит на some_routine
; больше ничего не происходит).
Сохранение этих регистров в вызове - это просто соглашение: это часть стандарта "«Двоичный интерфейс приложения» (ABI), представляющий собой набор соглашений, охватывающих использование регистров, использование стека, форматы данных и т. Д. - различные фрагменты кода (приложения, библиотеки и т. Д.), Которые соответствуют одному и тому же ABI, будут взаимодействовать друг с другом.
Если вы хотите, чтобы ваш код вызывался из других мест, ваш код должен соответствовать ABI, ожидаемому вызывающей стороной.например, если вы пишете некоторую подпрограмму сборки, которая должна вызываться из кода C, вам нужно будет соответствовать ABI, используемому кодом, который генерирует компилятор C.
Для обычного ABI MIPS этоозначает, что код, который вызывает вашу подпрограмму, будет предполагать, что любые значения, которые она поместила в $s0
- $s7
до вызова, все еще будут присутствовать после возврата вызова, но она будет не предполагать, что содержимоеиз $t0
- $t9
все те же.(Точно так же, если ваш код вызывает библиотечные процедуры (например), он может сделать те же предположения: после возврата вызова все, что было в $s0
- $s7
, было сохранено, но $t0
- $t9
может содержать все что угодно.)
Это означает, что ваш код должен сохранить любой из $s0
- $s7
перед их изменением и восстановить их перед возвратом.То, что происходит между их сохранением и восстановлением, не имеет значения - все, что имеет значение, это то, что вызывающая сторона не видит никаких изменений.
Так что, да, ваша идея верна (и действительно, разумная вещь, которую нужно здесь сделать).
(Обратите внимание, что ваши подпроцедуры (procedure1
, prodcedure2
и т. Д.) не обязательно должны соответствовать этому стандартному ABI, , если они только когда-либо вызываются из вашей основной процедуры и не обращаются к внешним подпрограммам - потому что, в этом случае, они должны взаимодействовать только с вашей основной процедурой, а не с любым другим кодом. Но это хорошая идеяв любом случае следуйте ABI, если только для этого нет веских оснований; это облегчает чтение кода, делает в будущем более общедоступной одну из внутренних процедур при необходимости, облегчает добавление вызовов в другой код и т. д.)