Я сейчас пишу игрушечный компилятор в качестве домашнего задания, ориентированного на архитектуру MIPS.
Существует 18 регистров, которые обычно доступны при переводе с языков более высокого уровня: s0
до s7
, которые сохраняются вызываемым абонентом, и t0
до t9
, которые сохраняются вызывающим абонентом.
С этими 18 доступными регистрами возникает вопрос: какой регистр мне выбрать при выполнении перевода функции.
У каждого сета есть свои плюсы и минусы:
- Регистры, сохраненные в Callee, должны быть сохранены и восстановлены из стека в начале и конце функции соответственно.
- Сохраненные вызывающим регистры регистры должны быть сохранены и восстановлены из стека до и после вызова подпрограммы соответственно.
Мне ясно, что если я приму статическую стратегию использования этих регистров - какой бы она ни была, например, предпочтение регистров, сохраненных вызываемым абонентом, а не регистров, сохраненных вызывающим абонентом, - я не получу оптимальную производительность, поскольку, скорее всего, в этом не будет необходимости регистрация загрузки / магазинов.
Итак, есть ли хорошие практики использования этих двух наборов регистров?