При написании подпрограмм на языке ассемблера AVR (обычно это обработчик прерывания) иногда нужно сохранить в стек и потом восстановить оттуда регистр состояния процессора SREG. Однако простой командой pop SREG этого сделать нельзя, компилятор выдает ошибку.
../timerint.S: Assembler messages:
../timerint.S:9: Error: number must be positive and less than 32
../timerint.S:9: Error: register name or number from 0 to 31 required
make: *** [timerint.o] Ошибка 1
Ошибка происходит потому, что SREG не является регистром общего назначения, таким как R16, R24 и т. п. Поэтому для сохранения SREG в стек нужно использовать промежуточный регистр, например:
interrupt:
in r16, SREG ; сохранение SREG
...
out SREG, r16 ; восстановление SREG
reti
Для сохранения SREG в промежуточный регистр можно использовать команды ассемблера lds и sts. Также не следует забывать о том, что промежуточный регистр тоже нужно сохранять в стеке. Пример обработчика прерывания Timer0:
;////////////////////////////////////////////////////////////////////
; Обработчик прерывания таймера реального времени на ассемблере.
#include <avr/io.h>
.text
.global TIMER0_OVF_vect
TIMER0_OVF_vect:
push R24
lds R24, SREG
push R24
in R24, _SFR_IO_ADDR(TIMSK)
andi R24, ~(1<<TOIE0)
out _SFR_IO_ADDR(TIMSK), R24
pop R24
sts SREG, R24
pop R24
reti
|