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?
Preserving sreg in AVR interrupts
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.
Alternatively
PUSH Rn
LDS Rn, SREG
PUSH Rn
and
POP Rn
STS SREG, Rn
POP Rn
seems to be valid.
Close! But this doesn't save SREG -- I think it saves the EECR register. But at least I have verified that the above won't save/restore SREG. –
Janeejaneen
...The IN and OUT mnemonics operate on data registers 0 to 0x3F. When you access the same locations with LDS or STS, you need to add 0x20 to it. In this case, you would use
LDS Rn, SREG + 0x20
and STS SREG + 0x20, Rn
I'm surprised nobody caught that for almost five years! –
Janeejaneen © 2022 - 2024 — McMap. All rights reserved.
in
andout
instructions. – Russophobe