Конкретно эта последовательность помимо тупо сохранения rbp создаёт разметку кадров стека. Если все функции в цепочке вызовов делают так, то из любой функции можно проследить всю цепочку вызовов до неё зная только текущее значение rbp без какой бы то ни было дополнительной отладочной информации, потому что по адресу в rbp хранится rbp предыдущей функции, а по адресу rbp + 8 -- адрес возврата в предыдущую функцию. Но делать это, конечно же, необязательно. Например
gcc
вызванный с флагом
-fomit-frame-pointer
генерирует код без этой последовательности и использует rbp как ещё один регистр общего назначения.
Почему тогда все регистры не помещаются в стек?
Потому что есть документ называемый psABI, который определяет, какие регистры должна сохранять вызываемая функция. Например:
x86_64 psABI, раздел 3.2.1 "Registers".