|
Ваша дотошность достойна лучшего применения. Вы всегда такой педантично точный в деталях? Я бы даже сказал занудный. Но, наверное, к Вам этот термин не применим. Посему не принимайте мои слова.
Кстати, а какой прикол в нике 51 - у меня складывается устойчивое впечатление, что на самом деле у Вас есть другой (как это некоторые называют - официальный) ник.
Ваша неточность, о которой я имел несчастье высказаться, — это моя невнимательность к деталям. Которая порождена Вашей фразой, что мол у вопрошающего извлечение из стека производилось в регистр r0, вот Вы и автоматом написали r0. Но мы все тут знаем, что r0 в 51 и r0 в avr - это абсолютно разные вещи.
И напоследок приведу еще пример кода на ту же тему.
Без использования r0:
; считаем что на стеке ничего лишнего кроме адреса возврата
push acc
dec sp
dec sp
dec sp
mov a, #low
push acc
mov a, #high
push acc
inc sp
pop acc
reti
Фи. некрасиво и длинно.
Не сохраняя r0 - можно провернуть и такое, если знать подробнее о программе. Обычно при входе в прерывание сохраняется psw а затем переключается банк регистров на другой, чтобы не портить r0-r7. Потому, пока мы не сняли со стека psw, можно не сохранять r0 и все делать любым методом.
Но это еще не все. Я не люблю универсальные методы, поскольку они так или иначе избыточны. Дял чего обычно нужно возвращаться из прерывания в некую точку основного тела программы, но не в ту из которой мы ушли на прерывание? Обычно такой трюк нужен при организации вытесняющей многозадачности. Что это значит? А то, что нам неизвестно, как при переключении контекста задач сохраняются рабочие регистры, в том числе acc, psw - а потому какой конкретный метод подмены адреса возврата лучше применить - неизвестно. Посему я бы не стал так категорично и безаппеляционно, как Вы, предлагать методы решения этой задачи.
На самом деле ни я, ни Вы не ответили на вопрос правильно.
Я думаю, что правильный ответ на исходный вопрос должен был быть такой:
Для того, чтобы вернуться из подпрограммы прерывания в произвольную точку программы, необходимо заменить на стеке исходный адрес возврата на требуемый нам адрес и затем сделать reti, чтобы механизм обработки прерываний корректно восстановил свое состояние.
Вот и все. И как мне кажется, такой ответ звучал, но он потонул в наших с Вами примерах кода.
Послушайте: может быть Вы напишите короткую назидательную статью по этой теме, а я с удовольствием ее опубликую у себя в разделе "Практические советы"?
Может быть Вы даже можете привести пример кода, как тоже самое сделать на Си?
Я ответил на все Ваши вопросы и замечания? Если да, то дальнейшую дискуссию продолжать нет смысла.
Только не надо мне советовать идти гулять - у нас тут пока еще погода не гулятельная.
E-mail: info@telesys.ru