Архитектуры RISC, как правило, имеют меньше специальных инструкций или действий, и вместо этого для управления стеком используются стандартные инструкции. Обычно это означает, что программы больше, сам ЦП проще, а компилятору приходится сложнее оптимизировать.
Рассмотреть возможность:
int bar(int a)
{
return a * a;
}
void foo()
{
bar(22);
}
foo();
Здесь bar()
– это функция-лист, которая не выполняет дальнейших вызовов функций. Поэтому адрес возврата в LR
никогда не будет перезаписан. Как следствие, нет необходимости записывать его в стек вообще. Это сохраняет, загружает и сохраняет из/в память.
foo()
, с другой стороны, изменит LR
, потому что он вызывает функцию, поэтому ему нужно будет сохранить адрес возврата вызывающего объекта в стеке.
Сравните это с архитектурой, в которой вызов функции автоматически помещает адрес возврата в стек — такая оптимизация невозможна.
Все версии стандарта вызова процедур ARM определяют вызываемый объект сохраняет регистры для вызова функции — регистры, которые вызывающая сторона может ожидать при вызове функции. Если функция тривиальна, она снова не приводит к доступу к памяти.
В прерываниях время часто более критично. Процессоры ARM имеют набор теневых регистров, которые доступны только в состоянии прерывания. Это означает, что можно написать тривиальные обработчики прерываний, не требующие доступа к памяти.
person
marko
schedule
20.05.2019