Показать сообщение отдельно
Непрочитано 21.08.2010, 18:34  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: Как изменить адрес подпрограммы обработки прерывания?

Сообщение от alex_312 Посмотреть сообщение
А что мне удивятся, это вы удивитесь, когда посмотрите ассемблерный листинг и увидите что любое прерывание начинается с того что сохраняются все (практически все) регистры в стек, а перед выходом из прерывания они восстанавливаются из стека.
Я бы удивился, если бы Вы оказались правы. Но на самом деле:
Код:
uint8_t a;
volatile uint8_t result;

ISR(INT1_vect)
{
result  = a;
}
И листинг
Код:
11:       {
+0000002D:   921F        PUSH    R1               Push register on stack
+0000002E:   920F        PUSH    R0               Push register on stack
+0000002F:   B60F        IN      R0,0x3F          In from I/O location
+00000030:   920F        PUSH    R0               Push register on stack
+00000031:   2411        CLR     R1               Clear Register
+00000032:   938F        PUSH    R24              Push register on stack
12:       result  = a;
+00000033:   91800061    LDS     R24,0x0061       Load direct from data space
+00000035:   93800060    STS     0x0060,R24       Store direct to data space
+00000037:   918F        POP     R24              Pop register from stack
+00000038:   900F        POP     R0               Pop register from stack
+00000039:   BE0F        OUT     0x3F,R0          Out to I/O location
+0000003A:   900F        POP     R0               Pop register from stack
+0000003B:   901F        POP     R1               Pop register from stack
+0000003C:   9518        RETI                     Interrupt return
В стек идут 3 регистра и SREG. Три это почти все из 32?
А теперь то же, но через указатель. Т.е. то, что Вы предложили.
Код:
void Func(void);
typedef void (*FuncPtr_t)(void);

FuncPtr_t pFunc = Func;
uint8_t a;
volatile uint8_t result;

void Func(void)
{
result = a;
}

ISR(INT1_vect)
{
(*pFunc)();
}
И ее результат. Учтите, там только вызов функции, никакой полезной работы уже нет.
Код:
@00000032: __vector_2
21:       {
+00000032:   921F        PUSH    R1               Push register on stack
+00000033:   920F        PUSH    R0               Push register on stack
+00000034:   B60F        IN      R0,0x3F          In from I/O location
+00000035:   920F        PUSH    R0               Push register on stack
+00000036:   2411        CLR     R1               Clear Register
+00000037:   932F        PUSH    R18              Push register on stack
+00000038:   933F        PUSH    R19              Push register on stack
+00000039:   934F        PUSH    R20              Push register on stack
+0000003A:   935F        PUSH    R21              Push register on stack
+0000003B:   936F        PUSH    R22              Push register on stack
+0000003C:   937F        PUSH    R23              Push register on stack
+0000003D:   938F        PUSH    R24              Push register on stack
+0000003E:   939F        PUSH    R25              Push register on stack
+0000003F:   93AF        PUSH    R26              Push register on stack
+00000040:   93BF        PUSH    R27              Push register on stack
+00000041:   93EF        PUSH    R30              Push register on stack
+00000042:   93FF        PUSH    R31              Push register on stack
22:       (*pFunc)();
+00000043:   91E00060    LDS     R30,0x0060       Load direct from data space
+00000045:   91F00061    LDS     R31,0x0061       Load direct from data space
+00000047:   9509        ICALL                    Indirect call to (Z)
+00000048:   91FF        POP     R31              Pop register from stack
+00000049:   91EF        POP     R30              Pop register from stack
+0000004A:   91BF        POP     R27              Pop register from stack
+0000004B:   91AF        POP     R26              Pop register from stack
+0000004C:   919F        POP     R25              Pop register from stack
+0000004D:   918F        POP     R24              Pop register from stack
+0000004E:   917F        POP     R23              Pop register from stack
+0000004F:   916F        POP     R22              Pop register from stack
+00000050:   915F        POP     R21              Pop register from stack
+00000051:   914F        POP     R20              Pop register from stack
+00000052:   913F        POP     R19              Pop register from stack
+00000053:   912F        POP     R18              Pop register from stack
+00000054:   900F        POP     R0               Pop register from stack
+00000055:   BE0F        OUT     0x3F,R0          Out to I/O location
+00000056:   900F        POP     R0               Pop register from stack
+00000057:   901F        POP     R1               Pop register from stack
+00000058:   9518        RETI                     Interrupt return
В стек идут уже 14 регистров + SREG. 11 лишних, по два такта на PUSH - 22 лишних такта. А тут топикстартер из за 5 лишних расстраивается.
kison вне форума