прога увы ужасна ))) ну у кого не бывает по началу...
для начала сдвиг делается гораздо проще...есть прям такая команда ROL или ROR.. влево и право соответственно....
+ про стек.. в начале программы необходимо написать
- Код: Выделить всё • Развернуть
ldi tmp1,low(RAMEND) ; сдесь устанавливаем границы стека
out SPL,tmp1
ldi tmp1,high(RAMEND)
out SPH,tmp1
где tmp1 любой регистр.. в моем случае R16.. присвоить регистру имя можно так:
.def tmp1 = R16
начало программы рекомендуется начинать так:
- Код: Выделить всё • Развернуть
.org 0
rjmp START
.org 0x50
START:
суть в том, что начиная с 0 адреса лежат вектора прерываний, а диже если они не используются имеет смысл их обойти и расположить свой код после их области.. директива .org задает адрес для следующей за ней команды...
вашу программу я бы переписал так:
- Код: Выделить всё • Развернуть
.include "m16def.inc"
.def tmp1 = R16
;.def tmp2 = R17
.org 0 ; .org определяет адрес для следующих мнемоник
rjmp START ; тут осуществляем переход к метке старт минуя вектора прерываний
.org 0x50
START:
ldi tmp1,low(RAMEND) ; сдесь устанавливаем границы стека
out SPL,tmp1
ldi tmp1,high(RAMEND)
out SPH,tmp1
ldi tmp1,0xFF ;255
out DDRD,tmp1
ldi tmp1,0x00
out PORTD,tmp1
ldi tmp1, 1
povtor:
out PORTD, tmp1 ; вывод в порт значения аккамулятора
call delay ; тут все ясно )
rol tmp1 ;сдвиг влево (с ним одна проблема после того ак единица)
brcc povtor ;попадет в старший разряд то после повторнго сдвига в младшем
rol tmp1 ;бите будет ноль, и нужно еще раз сдвинуть... что тут и сделано
rjmp povtor ;сдвиг выполняется через бит C... проверяем его и если он равен 1
; сдвигаем еще
delay:
ldi r25,3
zad:
dec r25
brne zad
ret
Добавлено спустя 3 минуты 12 секунд:RAMEND по идее двухбайтный верхний адрес памяти.. определен в описании контроллера что подключается в первой строке программы... low() дает младший байт адреса high() соответственно старший