MIPS Элегантно ли использовать $ s0 ... etc reginsters внутри процедуры и восстанавливать ее в конце - PullRequest
2 голосов
/ 21 мая 2011

Я прочитал в руководстве по MIPS, что при вызовах процедур сохраняются только регистры $ s0-$ s7.Но я думаю (возможно, я ошибаюсь?), Что это не элегантно - создавать процедуры, которые имеют побочные эффекты - я думаю, что процедуры должны изменять только регистры $ v0, $ v1 и стек, если это необходимо (я прав?).Так что, по моему мнению, в моей процедуре я могу использовать только $ t0- $ t9 reginsters.Но когда я вызываю некоторые процедуры в моей процедуре, это может изменить $ t0- $ t9 регистеров.Поэтому я должен хранить временные регуляторы и восстанавливать их после вызова процедуры в моей процедуре.Но когда моя процедура выглядит следующим образом:

call procedure1
compute something on temporary reginsters

call procedure2
compute something on temporary reginsters

call procedure3
compute something on temporary reginsters

...

моей процедуре требуется много обращений к памяти.Поэтому моя идея состоит в том, чтобы использовать:

Store at the begining of my procedure reginsters $s0-$s7.
Use reginsters $s0-$s7 in my procedure.
Restore old values of reginsters $s0-$s7.

Это элегантно и имеет ли это плохие последствия?

1 Ответ

4 голосов
/ 21 мая 2011

Я прочитал в руководстве по 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, если только для этого нет веских оснований; это облегчает чтение кода, делает в будущем более общедоступной одну из внутренних процедур при необходимости, облегчает добавление вызовов в другой код и т. д.)

...