Ассемблер (ASM) для AVR в вопросах и ответах
- Сообщения: 73
- Зарегистрирован: Сб авг 23, 2014 21:49:24
Всем привет. Вопрос следующий: как записать 16 розрядное число в 2 регистра да так, чтобы его можно было использовать как счетчик секунд, который настраивается кнопками и потом вести отсчет?
- Реклама
любым известным вам способом - совершенно без разницы, как именно.Дима_Медвед писал(а):как записать 16 розрядное число в 2 регистра
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 73
- Зарегистрирован: Сб авг 23, 2014 21:49:24
Смысл не в простой записи, а в возможности отсчета секунд, к примеру 9999сек. Как организовать алгоритм счетчика секунд, который будет их отсчитывать.ARV писал(а):любым известным вам способом - совершенно без разницы, как именно.
вы хотите увидеть ассемблерный листинг, который реализует вашу задумку? или о чем идет речь?
ведь "алгоритм" прост до безобразия:
1. заносим в регистровую пару нужное число
2. настраиваем таймер на прерывания 1 раз в секунду (или чаще)
3. создаем обработчик прерывания, в котором уменьшаем содержимое регистровой пары
4. когда оба регистра этой пары станут равны 0 - делаем, что хотим (время истекло)
что у вас вызывает затруднения?
ведь "алгоритм" прост до безобразия:
1. заносим в регистровую пару нужное число
2. настраиваем таймер на прерывания 1 раз в секунду (или чаще)
3. создаем обработчик прерывания, в котором уменьшаем содержимое регистровой пары
4. когда оба регистра этой пары станут равны 0 - делаем, что хотим (время истекло)
что у вас вызывает затруднения?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 73
- Зарегистрирован: Сб авг 23, 2014 21:49:24
Как оформить обработчик прерываний, тоесть как правильно задать алгоритм уменшения регистровой пары.ARV писал(а):что у вас вызывает затруднения?
- Реклама
Дима_Медвед писал(а):к примеру 9999сек
Код: Выделить всё
ldi r30,low(9999)
ldi r31,high(9999)1. декремент младшего регистра.Дима_Медвед писал(а):алгоритм уменшения регистровой пары
2. если появился перенос, то младший регистр обнулить и декремент старшего регистра.
Последний раз редактировалось pyzhman Вт апр 21, 2015 13:39:30, всего редактировалось 1 раз.
Docendo discimus
да какой алгоритм уменьшения регистровой пары может быть?! вычесть из "младшего" регистра 1, если флаг переноса установлен - вычесть 1 из "старшего"?! в ассемблерных командах даже "если" не нужно, ибо есть команды вычитания сразу с учетом переноса...
вы не темните, прямо говорите, что не понятно. или давайте ваш код на рассмотрение и поиск ошибок в нем.
вы не темните, прямо говорите, что не понятно. или давайте ваш код на рассмотрение и поиск ошибок в нем.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Код: Выделить всё
SBIW Rx,1- Сообщения: 73
- Зарегистрирован: Сб авг 23, 2014 21:49:24
Вот он, буду очень благодарен за помощь, т.к. новичок в написании програм.ARV писал(а):вы не темните, прямо говорите, что не понятно. или давайте ваш код на рассмотрение и поиск ошибок в нем.
ссылка на файл http://ifolder.com.ua/8rsajf8cvg8l.html
Спойлер
;Fclk=8MhZ;PORTD = Індикатор
;PORTC = 0,1,2,3 Спільний катод
;PORTB = 0,1,2,3,4,5 Налаштування режиму роботи
.include "m8def.inc"
.equ T = 34285
.equ T_ind = 100
.def timeL = r20
.def timeH = r21
.def tmp1 = r22
.def tmp2 = r23
.def digit = r24
.def ind_H = r25
.def ind_L = r26
.org 0x000
rjmp init
.org 0x008
rjmp time_check
.org 0x009
rjmp dinamic_ind
init:
ldi r16, high(RAMEND)
ldi r17, low(RAMEND)
out SPH, r16
out SPL, r17
ldi r16, 0xFF
out DDRD, r16
out DDRC, r16
out PORTB, r16
ldi digit, 4
ldi r16, T_ind
out TCNT0, r16
ldi r16, 1<<CS02
out TCCR0, r16
ldi r16, 1<<TOIE0
out TIMSK, r16
sei
;========================
main:
sbis PINB, 0 ; Перевірка 1 кнопки
rjmp add_1 ; Переходимо для збільшення часу на 1
sbis PINB, 1 ; Перевірка 2 кнопки
rjmp add_10 ; Переходим для збільшення часу на 10
sbis PINB, 2 ; Перевірка 3 кнопки
rjmp add_100 ; Переходим для збільшення часу на 100
sbis PINB, 3 ; Перевірка 4 кнопки
rjmp sub_1 ; Переходим для зменшення часу на 1
sbis PINB, 4 ; Перевірка 5 кнопки
rjmp sub_10 ; Переходим для зменшення часу на 10
sbis PINB, 5 ; Перевірка 6 кнопки
rjmp sub_100 ; Переходим для зменшення часу на 100
rcall bin_to_bcd
stop_check:
sbis PINB, 6 ; Перевірка 7 кнопки
rjmp start_stop; Переходим для запуску/зупинки таймера
rjmp main ; Ніяка кнопка не натиснута
;========================
add_1:
rcall delay_contacts ; Затримка на тремтіння контактів
inc timeL ; Збільшуємо час на 1(молодший регістр)
brcc wait_1 ; Регіср "закінчився" (встановлено прапорець переносу)
dec timeL ; Повертаємо минуле значення
inc timeH ; Збільшуємо на 1 (старший регістр)
wait_1:
sbic PINB, 0 ; Перевірка відпускання кнопки
rjmp output ; Переходим на вихід
rjmp wait_1 ; Кнопку не відпущено
add_10:
rcall delay_contacts
ldi r16, 10
add timeL, r16
brcc wait_2
subi timeL, 10
add timeH, r16
wait_2:
sbic PINB, 1
rjmp output
rjmp wait_2
add_100:
rcall delay_contacts
ldi r16, 100
add timeL, r16
brcc wait_3
subi timeL, 100
add timeH, r16
wait_3:
sbic PINB, 2
rjmp output
rjmp wait_3
sub_1:
rcall delay_contacts
dec timeH
brcc wait_4
inc timeH
dec timeL
wait_4:
sbic PINB, 3
rjmp output
rjmp wait_4
sub_10:
rcall delay_contacts
ldi r16, 10
subi timeL, 10
brcc wait_5
add timeH, r16
subi timeL, 10
wait_5:
sbic PINB, 4
rjmp output
rjmp wait_5
sub_100:
rcall delay_contacts
ldi r16, 100
subi timeL, 100
brcc wait_6
add timeH, r16
subi timeL, 100
wait_6:
sbic PINB, 5
rjmp output
rjmp wait_6
output:
rcall delay_contacts
rcall bin_to_bcd
rjmp main
start_stop:
brts stop
ldi r17, high(T)
ldi r16, low(T)
out TCNT1H, r17
out TCNT1L, r16
ldi r16, 1<<CS10| 1<<CS11
out TCCR1B, r16
ldi r16, 1<<TOIE1
out TIMSK, r16
set
rcall delay_contacts
sbic PINB, 6
wait_7:
rjmp stop_check
rjmp wait_7
stop:
ldi r16, 0x00
out TCCR1B, r16
clt
rcall delay_contacts
wait_8:
sbic PINB,6
rjmp main
rjmp wait_8
;=======================
time_check:
brts dec_h
dec timeL
brcc output_3
set
inc timeL
dec_h:
dec timeH
output_3:
ldi r16, high(T)
ldi r17, low(T)
out TCNT1H, r16
out TCNT1L, r17
reti
;===========
dinamic_ind:
ldi r16, T_ind
out TCNT0 , r16
rcall bin_to_bcd
dec digit
brne not_four
ldi digit, 4
digit_4:
mov YL, timeH
lsr YL
lsr YL
lsr YL
lsr YL
ldi r16, 0b00000111
out PORTC, r16
rjmp output_2
not_four:
cpi digit, 3
breq digit_3
cpi digit, 2
breq digit_2
digit_1:
mov YL, timeL
andi YL, 0x0F
ldi r16, 0b000001110
out PORTC, r16
rjmp output_2
digit_3:
mov YL, timeH
andi YL, 0x0F
ldi r16, 0b00001011
out PORTC, r16
rjmp output_2
digit_2:
mov YL, timeL
lsr YL
lsr YL
lsr YL
lsr YL
ldi r16, 0b00001101
out PORTC, r16
output_2:
ldi ZH, high(1<<ind_codes)
ldi ZL, low(1<<ind_codes)
ldi YH, 0
add ZL, YL
adc ZH, YH
lpm r16, Z
out PORTD, r16
reti
;================
bin_to_bcd:
cli
mov ind_L, timeL
mov ind_H, timeH
ldi tmp1, 100
ldi tmp2, -1
loop_1:
inc tmp2
sub ind_L, tmp1
brsh loop_1
dec ind_H
brpl loop_1
add ind_L, tmp1
mov ind_H, tmp2
ldi tmp1, 10
ldi tmp2, -1
loop_2:
inc tmp2
sub ind_L, tmp1
brsh loop_2
add ind_L, tmp1
swap tmp2
add ind_L, tmp2
ldi tmp2, -1
loop_3:
inc tmp2
sub ind_H, tmp1
brsh loop_3
add ind_H, tmp1
swap tmp2
add ind_H, tmp2
sei
ret
;Затримка на тремтіння контактів кнопки=========
delay_contacts:
cli
ldi r16, 0x00
out PORTD, r16
ldi r16, 255
dm1: ldi r17, 255
dm2: dec r17
brne dm2
dec r16
brne dm1
sei
ret
;Таблиця кодів===================
ind_codes:
.db 0b11111100, 0b01100000
.db 0b11011010, 0b11110010
.db 0b01100110, 0b10110110
.db 0b10111110, 0b11100000
.db 0b11111110, 0b11110110
Бегло посмотрел в студии.
Ошибка
Пожелания
Максимально сократить длинные обработчики прерываний и ввести запоминание статуса и используемых в них регистров с восстановлением их при выходе.
Как минимум в 2 раза поднять частоту вывода на индикацию. Частота 50/секунду маловата.
Ошибка
Код: Выделить всё
output_2:
ldi ZH,high(ind_codes*2)
ldi ZL,low(ind_codes*2)
;ldi ZH, high(1<<ind_codes)
;ldi ZL, low(1<<ind_codes)
Максимально сократить длинные обработчики прерываний и ввести запоминание статуса и используемых в них регистров с восстановлением их при выходе.
Как минимум в 2 раза поднять частоту вывода на индикацию. Частота 50/секунду маловата.
- Сообщения: 1495
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Спойлер
Код: Выделить всё
//==================
Main:
wdr
rcall Service_Timers
rcall Proc_FSM_Outputs
// bla-bla
st Y, XL // Младший байт переменной для преобразования HEX-DEC
std Y+1, XH // Старший байт переменной для преобразования HEX-DEC
rcall Hex_Dec
ldx HEX_DEC_BUFFER+1
ldy DISPLAY_BUFFER
ldi r17, 4
Main_Cycle:
ld r16, X+
st Y+, r16
dec r17
brne Main_Cycle
M_4:
#if (PROJECT==WORK)
sleep
nop
#endif
rjmp Main
//==================
/************************************************************************/
#if (BCD==YES)
.dseg
HEX_DEC_BUFFER:
.equ HEX_DEC_BUFFER_LENGHT = 5
.byte HEX_DEC_BUFFER_LENGHT
.cseg
Hex_Dec:
ldx HEX_DEC_BUFFER
ldi r17,HIGH(10000)
ldi r16,LOW(10000)
rcall Digit
st X+,r18
ldi r17,HIGH(1000)
ldi r16,LOW(1000)
rcall Digit
st X+,r18
ldi r17,HIGH(100)
ldi r16,LOW(100)
rcall Digit
st X+,r18
ldi r17,HIGH(10)
ldi r16,LOW(10)
rcall Digit
st X+,r18
mov r16,r14
// ori r16,0x30
st X+,r16
Hex_Dec_End:
ret
Digit:
ldi r18,-1
Digit_Cycle:
inc r18
sub r14,r16
sbc r15,r17
brsh Digit_Cycle
add r14,r16
adc r15,r17
// ori r18,0x30
ret
#endif
//==================
//==================
.equ ANOD_ONE = 1<<5
.equ ANOD_TEN = 1<<4
.equ ANOD_HANDRED = 1<<3
.equ ANOD_THOUSAND = 1<<2
.equ A = 1<<6
.equ B = 1<<7 // A
.equ C = 1<<3 // F B
.equ D = 1<<2 // G
.equ E = 1<<1 // E C
.equ F = 1<<5 // D
.equ G = 1<<4
.equ H = 1<<0
//------------------------------------------------------------------------
//------------------------------------------------------------------------
.equ ZERO = A+B+C+D+E+F
.equ ONE = B+C
.equ TWO = A+B+D+E+G
.equ THREE = A+B+C+D+G
.equ FOUR = B+C+F+G
.equ FIVE = A+C+D+F+G
.equ SIX = A+C+D+E+F+G
.equ SEVEN = A+B+C
.equ EIGHT = A+B+C+D+E+F+G
.equ NINE = A+B+C+D+F+G
//==================
.dseg
//==================
DISPLAY_BUFFER:
.equ DISPLAY_BUFFER_SIZE = 4
.byte DISPLAY_BUFFER_SIZE
//==================
.cseg
//==================
.macro Proc_7_Segm_Ind
mov CNT, CNT_7_SEGM_IND
clr ZH
mov ZL, CNT
lsl ZL
subi ZL, LOW(-(Table_7_Segm_Ind*2))
sbci ZH, HIGH(-(Table_7_Segm_Ind*2))
lpm CNT_7_SEGM_IND, Z+
lpm ANODS, Z
ldz DISPLAY_BUFFER
addw Z, CNT, RCLR
ld ZL, Z
clr ZH
subi ZL, LOW(-(Table_7_Segm_Char*2))
sbci ZH, HIGH(-(Table_7_Segm_Char*2))
lpm KATODS, Z
.endmacro
//------------------------------------------------------------------------
//------------------------------------------------------------------------
Table_7_Segm_Ind:
.db 0x01, ANOD_THOUSAND
.db 0x02, ANOD_HANDRED
.db 0x03, ANOD_TEN
.db 0x00, ANOD_ONE
Table_7_Segm_Char:
.db ZERO, ONE
.db TWO, THREE
.db FOUR, FIVE
.db SIX, SEVEN
.db EIGHT, NINE
//==================
.equ ANODS_PORT = PORTA
.equ ANODS_PIN = PINA
.equ ANODS_DDR = DDRA
.equ KATODS_PORT = PORTC
.equ KATODS_PIN = PINC
.equ KATODS_DDR = DDRC
.equ ANODS_MASK = ANOD_THOUSAND+ANOD_HANDRED+ANOD_TEN+ANOD_ONE
.equ KATODS_MASK = A+B+C+D+E+F+G
Def_Err_ID ERR_ID_PROC_OUTPUTS
.dseg
_PROC_OUTPUTS:
.byte 1
.cseg
Proc_FSM_Outputs:
ldy _PROC_OUTPUTS
Proc_FSM Tab_FSM_Proc_Outputs
Proc_Outputs_Init:
in RSREG, SREG
cli
in r16, ANODS_DDR
ori r16, ANODS_MASK
out ANODS_DDR, r16
out SREG, RSREG
Set_Timer Par_Timer_Proc_Outputs
Set_State Proc_Outputs_Set_State, _PROC_OUTPUTS_RUN
Proc_Outputs_Run:
Proc_Timer Par_Timer_Proc_Outputs
brtc Proc_Outputs_Run_End
Proc_7_Segm_Ind
in RSREG, SREG
cli
in r16, ANODS_PORT
andi r16, ~ANODS_MASK
out ANODS_PORT, r16
out KATODS_DDR, RCLR
in r16, ANODS_PORT
or r16, ANODS
out ANODS_PORT, r16
out KATODS_DDR, KATODS
out SREG, RSREG
Set_Timer Par_Timer_Proc_Outputs
Proc_Outputs_Run_End:
ret
Proc_Outputs_Set_State:
st Y, r16
ret
Tab_FSM_Proc_Outputs:
.db tab_h(_PROC_OUTPUTS), MAX_PROC_OUTPUTS_STATES, tab_h(Tab_Jmp_Proc_Outputs), ERR_ID_PROC_OUTPUTS
Tab_Jmp_Proc_Outputs:
.equ MAX_PROC_OUTPUTS_STATES = 2
.equ _PROC_OUTPUTS_INIT = 0
.db tab_h(Proc_Outputs_Init)
.equ _PROC_OUTPUTS_RUN = 1
.db tab_h(Proc_Outputs_Run)
Par_Timer_Proc_Outputs:
par_timer ST_PROC_OUTPUTS, 1<<ST_UNLOCK_FLG, 1
Весь проект не отдам. Коммерческий. Причесывать, чтобы сюда выложить нет ни времени ни желания. Уже больше 2 лет не пишу на асме. Перекрестясь, переполз на си.
Снова за дисплейную развертку?
Да еще "коммерческий" ...
Тут "на дурняк" новинки выкладываешш - никого нах... не нахх...
(смотри пост от Пн апр 13, 2015 12:51:34 в http://radiokot.ru/forum/viewtopic.php? ... 1&start=60 , в частности открытый исходник под ассемблером исключительно под аппаратный арсенал АВРки - http://radiokot.ru/forum/download/file.php?id=213673 )

Да еще "коммерческий" ...
Тут "на дурняк" новинки выкладываешш - никого нах... не нахх...
(смотри пост от Пн апр 13, 2015 12:51:34 в http://radiokot.ru/forum/viewtopic.php? ... 1&start=60 , в частности открытый исходник под ассемблером исключительно под аппаратный арсенал АВРки - http://radiokot.ru/forum/download/file.php?id=213673 )
Доброго дня, уважаемые коты. Помогите решить проблему, связанную с работой оперативной памяти.
Стоит такая задача:
При попадании в "эту часть кода" (нажатие кнопки), нужно загрузить значение и регистра в оперативную память. И при следующем попадании надо загрузить значение из того же регистра в следующую ячейку ОЗУ, относительно предыдущего раза. Ну и так далее. Я попробовал сделать так:
Собственно, вопрос, как правильно написать увеличение адреса оперативки, куда нужно записать?
Стоит такая задача:
При попадании в "эту часть кода" (нажатие кнопки), нужно загрузить значение и регистра в оперативную память. И при следующем попадании надо загрузить значение из того же регистра в следующую ячейку ОЗУ, относительно предыдущего раза. Ну и так далее. Я попробовал сделать так:
Код: Выделить всё
.def R16 REGISTER ;* Тут лежит то, что необходимо грузить в ОЗУ
.def R17 Temp
.def R18 Temp1
SRAMByte: .byte 1 ;* Место в ОЗУ, куда грузим в ПЕРВЫЙ раз
SRAMCounter: .byte 1 ;* Здесь находится счётчик, который считает, сколько раз мы уже бывали в этом цикле.
;Сделан для того, чтобы на его значение увеличивать адрес SRAMByte при записи в ПЗУ.
LDS Temp, SRAMCounter1 ; Выгружаем из ОЗУ текущее значение счётчика (при первом проходе цикла оно равно 0).
[b]SRAMByte+Temp,REGISTER ; На эту строку компилятор сообщает ошибку о неожиданном REGDEF. Я это видел как адрес первой ячейки оперативки(ну относительно первой)+смещение из
; счётчика.[/b]
inc Temp ; Увеличить счётчик
STS SRAMCounter1,Temp ; Записать его значение в ОЗУ
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
- Сообщения: 1495
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Весь проект выкладывать смысла нет. Потому активно применяются конечные автоматы, таймерная служба из программных таймеров. Псевдопараллельность процессов. Объяснять у меня эти вещи нет времени. Готовить проект, чтобы выскрести из него код для заказа нет ни времени ни желания. Почему, я написал выше. Так как разговор зашел за 7 сегментные индикаторы, я вложил куски кода. Берите и пользуйтесь.BOB51 писал(а):Да еще "коммерческий" ...
- Сообщения: 1495
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Для работы с ОЗУ есть регистровые пары X, XL r26, XH r27; Y, YL r28, YH r29; Z, ZL r30, ZH r31.
С ОЗУ могут работать все три регистровые пары XYZ, с flash памятью только регистровая пара Z.
Купите или скачайте книгу Вольфганг Трамперт "AVR-RISC микроконтроллеры фирмы ATMEL". Там все подробно разжевано, даны примеры, программы на асме.
Посмотрите выше в моем примере, как работать с ОЗУ. Читайте даташиты, там написано как использовать регистры и ОЗУ.
С ОЗУ могут работать все три регистровые пары XYZ, с flash памятью только регистровая пара Z.
Купите или скачайте книгу Вольфганг Трамперт "AVR-RISC микроконтроллеры фирмы ATMEL". Там все подробно разжевано, даны примеры, программы на асме.
Посмотрите выше в моем примере, как работать с ОЗУ. Читайте даташиты, там написано как использовать регистры и ОЗУ.
Спасибо за наводку, поищу. Вернее точно найду. P.S. Я не полное дно, просто кодил 6 часов подряд, в конце дня наткнулся на проблему, решил спросить на форуме 
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Кусок примера работы с кольцевым буфером в оперативке:Мikа писал(а): Собственно, вопрос, как правильно написать увеличение адреса оперативки, куда нужно записать?
Код: Выделить всё
Ring_Buff: .byte 128
Ring_Buff_Count: .byte 1
LDI ZL, LOW(Ring_Buff) ;Вычисляем текущее положение
LDI ZH, HIGH(Ring_Buff) ;указателя кольцевоого буфера
LDS R16,Ring_Buff_Count ;Загружаем счётчик кольцевого буфера
CLR R15
ADD ZL,R16 ;Вычисляем смещение текущего
ADC ZH,R15 ;положения буфера от нуля
ST Z+,R17 ;Заносим текущее значение
ST Z,R18 ;АЦП в кольцевой буфер
LDS R16,Ring_Buff_Count ;Сдвигаем указатель кольцевого буфера
SUBI R16,2
STS Ring_Buff_Count,R16Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
- Сообщения: 1495
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Я не понял, что тебе точно надо.
Третий вариант самый жручий по размеру кода. одна команда lds, sts занимает 4 байта. Так как адрес абсолютный.
Код: Выделить всё
// Вариант 1, если программа небольшая и указатель X больше нигде не используется.
clr CNT // где-то инициализируем CNT
ldi XL, LOW (BUFFER)
ldi XH, HIGH (BUFFER) // Где-то устанавливаем начальный адрес твоего буфера.
Programma:
st X+, CNT // Записываем, автоматически постинкремент указателя адреса.
// Вариант 2, если указатель X используется.
clr CNT // где-то инициализируем CNT
ldi XL, LOW (BUFFER)
ldi XH, HIGH (BUFFER) // Где-то устанавливаем начальный адрес твоего буфера.
movw r15:14, XH:XL
movw r14, XL // Аналогично.
Programma:
movw XL, r14 // Восстанавливаем указатель.
st X+, CNT // Записываем, автоматически постинкремент указателя адреса.
movw r14, XL // Сохраняем указатель.
// Вариант 3, если указатель X используется.
clr CNT // где-то инициализируем CNT
ldi XL, LOW (BUFFER)
ldi XH, HIGH (BUFFER) // Где-то устанавливаем начальный адрес твоего буфера.
sts SAVE_BUFFER_L, XL
sts SAVE_BUFFER_H, XH
Programma:
lds XL, SAVE_BUFFER_L // Восстанавливаем указатель.
lds XH, SAVE_BUFFER_H
st X+, CNT // Записываем, автоматически постинкремент указателя адреса.
sts SAVE_BUFFER_L, XL // Сохраняем указатель.
sts SAVE_BUFFER_H, XH
Seriyvolk, Demiurg, спасибо, то, что надо, щас только полностью осознаю в голове, что происходит в программе и проблема решена 
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Синтаксис:На эту строку компилятор сообщает ошибку о неожиданном REGDEF.
.DEF Символическое_имя = Регистр
Пример:
.DEF temp=R16
.DEF ior=R0


