Это зависит от платформы, но, как правило, все работает.
На архитектурах, с которыми я больше всего знаком, адрес вызова (он же return) находится в регистре $ ra, а стек - там, где он был оставлен вызывающей стороной. Так что происходит, когда адрес возврата помещается в стек, как и базовый указатель вашего (вызывающего), а затем обновляется базовый указатель, чтобы указать, где находится стек, и стек продолжает ползти вверх. Точный порядок расположения вещей и того, что установлено, когда я не помню, но обычно вызываемый абонент должен спасти от регистров, которые будут засорены. Таким образом, вызывающей функции не нужно сохранять все, если вызываемая функция использует только один или два регистра. (На самом деле регистр адреса возврата тот же - он не будет помещен в стек, если функция больше ничего не вызывает.)
На самом деле это довольно легко выполнить, если вы разберете программу и взгляните на пролог функции и эпилог. Все они следуют довольно распространенным схемам «хранить все» вверху и «восстанавливать все» внизу. (Обратите внимание, что иногда существуют «специальные» регистры, которые никогда не сохраняются и не восстанавливаются, и компилятор знает, что он может рассчитывать только на значения, являющиеся связными, если не было вызовов функций. В MIPS я думаю, что они являются регистрами S, а ппц их называет т?)