Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/22: Рейтинг темы: голосов - 22, средняя оценка - 4.73
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
1

Подмена стека

16.01.2013, 23:41. Просмотров 3986. Ответов 10
Метки нет (Все метки)

Возникла такая задачка: при определенном прерывани необходимо СРОЧНО выполнить одну ПЕРВОСТЕПЕННУЮ и довольно громоздкую процедуру, и при ее выполнении оставить возмоность отрабатывать другим прерываниям (не хочу заморачиваться с прерыванием в прерывании), поэтому пришла в голову такая мысль как подмена стека!

Контроллер отрабатывает наше прерывание, при этом сохраняет в стек адресс возврата из прерывания. Как только мы вошли в прерывание, первым делом мы достаем из стека адрес возврата и сохраняем его в регистре Z. Затем в стек помещается нужный адрес перехода к началу этой важной процедуры. Потом идет команда reti и мы возвращаемся из прерывания не туда откуда попали в прерывание, а в эту самую процедуру. Выполняем процедуру и в конце переходим по адресу находящемуся в регистре Z, то есть туда откуда перешли в прерывание. Ну вобщем откуда вышли, туда и вернулись. Надеюсь что не слишком перемудрил.

Конечно можно было бы поставить флаг в прерывании, потом вернуться из него и, дойдя до условия проверки наличая соответствущего флага, перейти к выполнению моей процедуры. НО! Пока программа дойдет до туда может пройти много времени, а мне нужно по возможности быстрее выполнить эту процедуру. Да и проверка лишних условий загромождает основную программу. На мой взгляд такой подход с подменой стека упростит ее.

Вобщем тут встают 2 вопроса:
1. Если я правильно понимаю, так как аресация памяти программ двухбайтная, то при прерывании в стек сохраняется адрес возврата - тоже 2х байтное число. Какой байт адреса лежит сверху стека? старший или младший? То есть, как мне корректно достать адрес из стека и положить туда новый, чтобы потом оба перехода осуществлялись правильно?
Код
pop high(Z)
pop low(Z)
ldi temp, low_byte
push low_byte
ldi temp, high_byte
push high_byte
или же наоборот?
Код
pop low(Z)
pop high(Z)
ldi temp, high_byte
push high_byte
ldi temp, low_byte
push low_byte
2. Как в программе вычислить тот самый адрес начала моей процедуры? Ведь программа - только текст, адресов куда пишутся комманды не видно!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.01.2013, 23:41
Ответы с готовыми решениями:

Вращение стека
Можно ли прокручивть стек? Мне просто нужна информация с самого низа стека,...

Трассировка стека в Си
Ищу какое-нибудь решение для решения задачи Трассировки стека в Си. Например,...

Переполнение стека
Данная программа выполняет конфигурирование АЦП для работы в DMA режиме со...

WinAver C, указатель стека
Проект на меге8, довольно большой, компилирован на WinAvr C. С одной из...

Программа на С,переполнение стека
Имеется программа: main() { //сдесь обьявляются много переменных int a1;...

10
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
16.01.2013, 23:46 2
чтоб не думать в отладчике проверьте так и этак
0
stt
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
16.01.2013, 23:50 3
Вот это покури: http://iosyitistromyss.ru/avr-uchebnyj- ... aniya.html
0
dikor
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 918
17.01.2013, 00:02 4
О! Вы изобрели многозадачную ОС и шедуллер!
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
17.01.2013, 00:14 5
Цитата Сообщение от dikor
О! Вы изобрели многозадачную ОС и шедуллер!
Вот это я крут! Не думал, что так быстро дойду до написания своей собственной операционной системы))) А мне за изобретение награду дадут? Нужно срочно патентовать)))
Да и... что такое шедуллер?

На вопрос №2 ответите - возьму в долю)))
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
17.01.2013, 00:17 6
>>Да и... что такое шедуллер?

по-моему что-то с дулей связано...
0
С_Ч
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 53
17.01.2013, 00:21 7
Кажись ты перемудриваешь!!! По первому вопросу - идешь в отладчик (Студию) и зыришь как стек упаковывается. По второму вопросу - любую физическую точку программы ты можешь отследить директивой присвоения метке программного счетчика. Для AVR, если мне память не изменяет, это примерно так:
.set sss = PC
Это ты вставляешь перед своей процедурой и значение sss будет содержать физический адрес начала твоей процедуры.
0
S_Otix
0 / 0 / 0
Регистрация: 28.01.2010
Сообщений: 537
17.01.2013, 01:46 8
Цитата Сообщение от wypuk
Возникла такая задачка: при определенном прерывани необходимо СРОЧНО выполнить одну ПЕРВОСТЕПЕННУЮ и довольно громоздкую процедуру, и при ее выполнении оставить возмоность отрабатывать другим прерываниям (не хочу заморачиваться с прерыванием в прерывании), поэтому пришла в голову такая мысль как подмена стека!
Ну, а если за это время будет опять прерывание?

Как по мне замени
Код
 reti
на
Код
 sei
rjmp ТО_ШО_НАДО (а там вернешся по ret туда от куда пришел)
Если период прихода прерывания больше времени выполнения ПЕРВОСТЕПЕННОЙ довольно громоздкой процедуры. Иначе ...
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
17.01.2013, 01:47 9
2. Как в программе вычислить тот самый адрес начала моей процедуры?
Да просто всё
Код
SUDA:
Ldwi Z(X,Y),TUDA
PUSH ZH
PUSH ZL
ret

TUDA:
Ldwi Z(X,Y),SUDA
PUSH ZH
PUSH ZL
ret
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
17.01.2013, 01:56 10
Цитата Сообщение от wypuk
2. Как в программе вычислить тот самый адрес начала моей процедуры? Ведь программа - только текст, адресов куда пишутся комманды не видно!
Допустим процедура, которой надо передать управление находится под меткой «subr:», то делаете следующее:
Код
Ldi  ZL, low(subr)
Ldi  ZH, high(subr)
icall
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
18.01.2013, 10:43 11
Цитата Сообщение от S_Otyx
Если период прихода прерывания больше времени выполнения ПЕРВОСТЕПЕННОЙ довольно громоздкой процедуры. Иначе ...
Т.е. может возникнуть рекурсия. Нужно подумать как это разрулить. Спасибо за подсказку.
0
18.01.2013, 10:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.01.2013, 10:43

vTaskList() - размер стека
vTaskList() в каких попугаях выдает размер стека у задачи (байты,слова)?

срыв стека silabs C8051F410
Всем привет! Определяю кучу массивов. Когда часть из них закоментирую, то...

Организация памяти и стека и отладка в AVRstudio
Всем привет. Я новичок в мк avr. Прошу ногами сильно не пинать, за возможно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru