Search code examples
assemblyarduinoavratmel

Preserving sreg in AVR interrupts


What is the mechanism used to preserve the status register, sreg, in an AVR microcontroller? RETI implies that these bits are not on the stack. Is one of the general purpose registers also the sreg or something like that?


Solution

  • This is explained in every AVR datasheet. For example on page 8 of the ATtiny2313 datasheet it says:

    The Status Register is not automatically stored when entering an interrupt routine and restored when returning from an interrupt. This must be handled by software.

    You can achieve this by storing it in a temporary register:

     interrupt:
         in r16, SREG   ; save SREG
    
         ...
    
         out SREG, r16  ; restore SREG
         reti
    

    Also note that if you're accessing registers that are not exclusively used in this interrupt routine, you need to save those, too. Furthermore you can push the value of SREG to the stack if you're low on registers:

     interrupt:
         push r16      ; save global registers on stack
         push r17
         push r18
         in r16, SREG  ; save SREG
         push r16      ; do this if you want to use r16 in your interrupt routine
    
         ...
    
         pop r16       ; do this if you pushed SREG above
         out SREG, r16 ; restore SREG
         pop r18       ; restore global registers
         pop r17
         pop r16
         reti
    

    For more information look here.