Перейду к сути. Имеем предельно простую подпрограмму прерывания:
Код
#pragma vector= INT0_vect
__interrupt void Int0(void)
{
while(!BUTTON);
__indirect_jump_to(0);
}
__interrupt void Int0(void)
{
while(!BUTTON);
__indirect_jump_to(0);
}
Генерируется код:
Код
18 __interrupt void Int0(void)
\ Int0:
19 {
\ 00000000 93FA ST -Y, R31
\ 00000002 93EA ST -Y, R30
20 while(!BUTTON);
\ ??Int0_0:
\ 00000004 9BB1 SBIS 0x16, 0x01
\ 00000006 CFFE RJMP ??Int0_0
21 __indirect_jump_to(0);
\ 00000008 E0E0 LDI R30, 0
\ 0000000A E0F0 LDI R31, 0
\ 0000000C 9409 IJMP
\ 0000000E REQUIRE _A_PINB
22 }
\ Int0:
19 {
\ 00000000 93FA ST -Y, R31
\ 00000002 93EA ST -Y, R30
20 while(!BUTTON);
\ ??Int0_0:
\ 00000004 9BB1 SBIS 0x16, 0x01
\ 00000006 CFFE RJMP ??Int0_0
21 __indirect_jump_to(0);
\ 00000008 E0E0 LDI R30, 0
\ 0000000A E0F0 LDI R31, 0
\ 0000000C 9409 IJMP
\ 0000000E REQUIRE _A_PINB
22 }
Все выполняется верно (и в железе тоже). Пишу с ассемблерной вставкой:
Код
#pragma vector= INT0_vect //В выключеном состоянии ~1...1,5 мкА
__interrupt void Int0(void)
{
while(!BUTTON);
asm("jmp 0"); // Не "rjmp 0", а именно "jmp 0" !
}
__interrupt void Int0(void)
{
while(!BUTTON);
asm("jmp 0"); // Не "rjmp 0", а именно "jmp 0" !
}
Генерируется код:
Код
18 __interrupt void Int0(void)
\ Int0:
\ ??Int0_0:
19 {
20 while(!BUTTON);
\ 00000000 9BB1 SBIS 0x16, 0x01
\ 00000002 CFFE RJMP ??Int0_0
21 asm("jmp 0");
\ 00000004 940C0000 jmp 0
22 }
\ Int0:
\ ??Int0_0:
19 {
20 while(!BUTTON);
\ 00000000 9BB1 SBIS 0x16, 0x01
\ 00000002 CFFE RJMP ??Int0_0
21 asm("jmp 0");
\ 00000004 940C0000 jmp 0
22 }
И, как ни странно, все выполняется (и в железе тоже).
В таком случае возникает вопрос, откуда у ATtiny13 появилась выполняемая в реале команда "jmp", отсутствующая в наборе команд для этого конкретного контроллера?