[an error occurred while processing this directive] [an error occurred while processing this directive]
Ответ: Это делается так (+)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
[an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive]

Отправлено Беня 14 ноября 2001 г. 14:23
В ответ на: От Асм к Си отправлено Петруха 14 ноября 2001 г. 11:39

Допустим у Вас есть обработчик прерывания
void my_interrupt( void), из которого Вам нужно вывалиться в функцию
void my_fun( void);
Можно сделать так :

void my_fun( void) {
...
}

void my_interrupt( void) interrupt 1 {
...

// а здесь делаем вываливание
#pragma asm
MOV A,SP ; берем указатель текущего положения стека
; в нем сверху лежит то, что пушировалось в стек
; а затем 2 байта - адрес,откуда ввалились в прерывание
; допустим, у меня пушируется только 2 байта : PUSH ACC и PUSH PSW
; это надо в листинге подсмотреть
DEC A
DEC A
; добрались до адреса точки возврата
MOV R0,A ; подменим этот адрес адресом нашей функции
MOV @R0,#HIGH my_fun
DEC A
MOV R0,A
MOV @R0,#LOW my_fun
#pragma endasm
}
после подмены адреса возврата адресом функции, выход будет осуществляться прямо на функцию.
Но, я поддерживаю коллег, что такими вещами увлекаться не стОит :
1) Надо вручную подсмотреть, сколько PUSH-ей делает компилятор при входе в прерывание (чтобы добраться до адреса возврата). Если после модификации обработчика изменится число PUSH-ей, то надо будет переделывать доступ к адресу возврата - добавить или убрать DEC A.
Т. е. надо все время следить!
2) Линкер не сможет корректно посчитать адреса для локальных переменных в Вашей функции my_fun(). Как выход - делать холостые вызовы этой функции из тех мест, где разрешены прерывания и где может быть вызвана эта функция. Что-то типа
if( 0) my_fun() ;

Короче, столько гемороя, что заниматься этим не стОит.

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru