Hi, this is a very basic question and I apologize to all the great freaks out here if these is a silly one.I wrote a simple program to find what exactly happens at the assembly during an interrupt routine . This is my program:
#include#include int main(void) { DDRD |= (1 << 2); PORTD &= ~(1 << 2); //Start the timer //Timer delay of 3usec TCCR0B = (1 << CS02) | (0 << CS01) | (1 << CS00); TIMSK0 = (1 << TOIE0); sei(); for(;;) { } } ISR(TIMER0_OVF_vect) { PORTD |= (1 << 2); }
The disassembler shows :
@00000036: main ---- int-test.c ----------------------------------------------------------------------------------- 6: { +00000036: 9A52 SBI 0x0A,2 Set bit in I/O register 9: PORTD &= ~(1 << 2); +00000037: 985A CBI 0x0B,2 Clear bit in I/Oregister 13: TCCR0B = (1 << CS02) | (0 << CS01) | (1 << CS00); +00000038: E085 LDI R24,0x05 Load immediate +00000039: BD85 OUT 0x25,R24 Out to I/O location 14: TIMSK0 = (1 << TOIE0); +0000003A: E081 LDI R24,0x01 Load immediate +0000003B: 9380006E STS 0x006E,R24 Store direct to data space 15: sei(); +0000003D: 9478 SEI Global Interrupt Enable +0000003E: CFFF RJMP PC-0x0000 Relative jump @0000003F: __vector_16 25: { +0000003F: 921F PUSH R1 Push register on stack +00000040: 920F PUSH R0 Push register on stack +00000041: B60F IN R0,0x3F In from I/O location +00000042: 920F PUSH R0 Push register on stack +00000043: 2411 CLR R1 Clear Register 26: PORTD |= (1 << 2); +00000044: 9A5A SBI 0x0B,2 Set bit in I/O register 28: } +00000045: 900F POP R0 Pop register from stack +00000046: BE0F OUT 0x3F,R0 Out to I/O location +00000047: 900F POP R0 Pop register from stack +00000048: 901F POP R1 Pop register from stack +00000049: 9518 RETI Interrupt return +0000004A: 94F8 CLI Global Interrupt Disable +0000004B: CFFF RJMP PC-0x0000 Relative jump
Now as far as I know what happens during an interrupt routine call is :
1. The peripheral device interrupts the processor.
2. Current instruction execution is completed.
3. The address of the next instruction is stored on the stack (either a hardware stack or a software stack).
4. The processor state (SREG) is stored in the Stack.
5. Address of the ISR (interrupt subroutine) are loaded into the program counter.
6. The processor executes the ISR.
7. The ISR execution completion is indicated by the RETI instruction (return from interrupt).
8. The processor loads the program counter with the value stored on the stack and normal program execution resumes.
Now at the disassembler code I find that at the ISR its like this :
@0000003F: __vector_16 25: { +0000003F: 921F PUSH R1 Push register on stack +00000040: 920F PUSH R0 Push register on stack +00000041: B60F IN R0,0x3F In from I/O location +00000042: 920F PUSH R0 Push register on stack +00000043: 2411 CLR R1 Clear Register
I know that R0 is being used to store the SREG value.But why is R1 also being pushed into the stack and popped later?