Поймал я странное поведение компилятора. (IAR C/C++ Compiler for AVR 6.12.1 (6.12.1.50500))
Долго искал почему после подключения в программу модуля proteus начал ругаться "обращение к памяти за её пределами".
И вот что нарыл:

Имеем кусочек кода
Код
uint16_t seconds = 0;

void main(void){
  seconds = 60 * 1 + 5;

Нажмите для просмотра прикрепленного файла
И дальше всё красиво работает.

Теперь инициализируем uint16_t seconds = 1; (не нулем!)
Нажмите для просмотра прикрепленного файла

R31 у нас не пустой. И компилятор не собирается его очищать, закидывая адрес только в R30 (модель памяти tiny). И команда ST Z, R16 стучится "совсем не туда".

Эх. Так всё лаконично и коротко получилось, а сколько я просидел за листингами, пока нашел причину.

В map-файле имеем:
Код
-------------------------------------------------------------------------
TINY_ID
  Relative segment, address: CODE 000003A4 - 000003A5 (0x2 bytes), align: 0
  Segment part 35.            Intra module refs:   seconds

Вот после этой инициализии, видимо, и остается в Z мусор.

Если включить сильную оптимизацию, то глюк исчезает.

___
P.S.
Если это реальный глюк компилятора, а не моя досадная ошибка, то можно и в тему компилятора iar перенести топик... а то я там только глупые вопросы задаю, а тут целый баг нарыл )))