Проще простого обратиться, все согласно документации 1. Резервируем нужное количество регистров в свойствах проекта, напр. 2 штуки это будет R14, R15.
2. Объявляем в проге, чего мы, собственно, хотим в этих регистрах хранить. Я захотел указатель на функцию, к примеру (Этих функций у меня много, и двиг между парами регистров как нельзя кстати) Итак, пишем:
__no_init __regvar void (* volatile Tfunc_ptr)(void) @14;
3. Теперь используем по ходу работы (присваиваем адреса функций):
Tfunc_ptr = Tisr_after_timeout; // если сработает -> на начало цикла
Tfunc_ptr = Tisr_after_preambula; // после преамбулы и пр.
А прерывание стало выглядеть очень лаконично:
__interrupt void Timer1_compa (void)
{
(*Tfunc_ptr)();
}
Что дает 2 асемблерные строчки:
..(*Tfunc_ptr)();
01F7 MOVW R31:R30, R15:R14
9509 ICALL
Вуаля! Правла, компилятор пихает в стек все что надо и не надо, но это уже другая история, сделать __raw и ручками, ручками.. ;-))