Это интересная идея. Я думаю, что есть две вещи, которые делают его менее привлекательным:
- Вызываемый должен зарезервировать пространство стека для худшего случая, независимо от этого.
- Чтобы сделать его эффективным, вам понадобятся специальные инструкции для хранения и загрузки наборов регистров за один раз. Такие инструкции были на Motorola 68000 (и, возможно, также на PowerPC), но они не были популярны.
Вот небольшая проработка того, как это должно работать:
Вы бы хотели, чтобы вызывающая сторона упаковывала список в машинное слово как битовый вектор. Затем вам нужно, чтобы вызываемый объект был побитовым - и с его собственным списком, у которого есть инструкция, которая сохраняет все регистры, названные результирующим битовым вектором.
Поскольку вам придется зарезервировать место в стеке для наихудшего случая, вы не сэкономите много - на современном суперскалярном неработающем процессоре записи в одну и ту же строку кэша почти бесплатно.
Также верно, что если вы действительно хотите минимизировать количество загрузок и хранилищ во время выполнения, вы просто идете со всеми регистрами сохранения вызовов. Эта стратегия также делает дешевым создание исключений и преимущественное переключение потоков, и по этой причине многие компиляторы (например, OCaml ) используют его. Callee-save регистры - это своего рода хак, чтобы попытаться сократить размер кода для инструкций по разливу и перезагрузке. Они работают во многих ситуациях и экономят место, потому что сайты вызовов намного превосходят количество определений процедур (в среднем процедура содержит несколько вызовов).
Для получения дополнительной информации о компромиссах между регистрами сохранения звонящего и сохранения звонящего, есть хорошая бумага Джек Дэвидсон и Дэвид Уолли .