Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.59/136: Рейтинг темы: голосов - 136, средняя оценка - 4.59
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
1

Макрос: сложение регистровой пары и одного регистра

24.04.2015, 00:37. Просмотров 24615. Ответов 43
Метки нет (Все метки)

Подскажите пожалуйста, как лучше сложить, скажем пару Z и R0. Естественно с минимальным количеством кода и тактов. Сходу написал:
add zl, r0
sbci zh, (-1)

А когда уже начал тестить увидел, что оно не работает)))
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.04.2015, 00:37
Ответы с готовыми решениями:

Как записать информацию из 16 битного регистра в два регистра по 8 бит
Как записать информацию из 16 битного регистра в два регистра по 8 бит. (То...

Сложение числа и регистровой пары
Как к получившемуся числу в DX:AX при умножении прибавить число? DX:AX + 1 =...

Сложение регистровой пары и двух байтов
Помогите с задачкой) Разработать программу которая производит сложение...

Сложение половинок регистра
Объясните плз как работает такое сложение и что находится в al и dh Какое...

Написать макрос сравнения без учета регистра
Пож, подскажите, есть макрос для сравнения текста двух ячеек, учитывающий...

43
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
24.04.2015, 01:34 2
.def zero = R1
clr zero
add zl,r0
adc zh,zero
0
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
24.04.2015, 11:21 3
Спасибо. Я так и сделал. Просто все идет в прерывании, а задача такая, что нужно каждый такт считать. А лишние push-pop сильно напрягают. Думал, может можно без 4-го регистра сделать, хитро как-нибудь. чтобы только перенос прибавить. Но получится только, если 2 команды добавить...
Попутно вопрос, а в каких еще операциях нужен обнуленный регистр? Есть смысл постоянно держать один под ноль, как делают сишные компиляторы? Может быть еще еденичка нужна?
0
Леаныч
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 207
24.04.2015, 12:26 4
Регистр ZERO бывает очень полезен. И для арифметики, и для обнуления в одно касание регистров I/O.
0
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
24.04.2015, 13:30 5
Ну по идее так же нужны бывают регистры ff и 1? Стоит их включать во все проекты и жертвовать на них 3 регистра? То есть в любой программе, при инициализации забить их и дальше нигде не менять и юзать как константы?
0
Леаныч
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 207
24.04.2015, 14:25 6
Скажу по себе - зеро нужен мне всегда, FF - иногда, 01 - редко.
Обычно в шаблон включены все три, но двумя последними при нехватке регистров, жертвую. )))
0
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
24.04.2015, 14:54 7
Уважаемый Леаныч)))) Дайте позырить на Ваш шаблон)))) Недавно тему поднимал эту. Сейчас как раз пишу шаблон для себя. Очень не хватает красивых и изящных решений!
Я почему спрашиваю на счет ВСЕГДА. Если их использовать всегда, то можно зашить намертво в макросы и как-бэ все! И юзать по коду команды быстрые и понятные, не заморачиваясь.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
24.04.2015, 20:45 8
Цитата Сообщение от rymomtsofto
Ну по идее так же нужны бывают регистры ff и 1? Стоит их включать во все проекты и жертвовать на них 3 регистра? То есть в любой программе, при инициализации забить их и дальше нигде не менять и юзать как константы?
Вы мой пример внимательно посмотрели? Вижу что нет. Потому что в главном файле я инициализирую регистры RCLR (0), RSER (0xFF), FLAGS (0).
Если вы ищете красивые решения, то пересмотрите еще раз мой пример. Я не претендую на "красивые" решения, но в свое время у меня были неплохие учителя. Bytt, кстати, один из них. Неплохие решения на главной сайте. iosyitistromyss.ru. В примерах DY HOTT-а много чего можно почерпнуть.
0
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
24.04.2015, 22:02 9
Да, невнимательно читал. Не обратил внимания. Забил в свой шаблончик) Теперь буду всегда пользовать!
Dimiurg, я тупил-тупил в Ваш код. Так я и не понял, как работает вся эта констуркция с автоматом? Я так думаю, что это машина обработки любого из автоматов, заюзанных в программе? Ну типа интерфейс. Сам состояния прочитает, сам установит, сам условия проверит? Как этим пользоваться? Вызов только из диспетчера?
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
24.04.2015, 22:28 10
Да, это этакое ядро конечных автоматов на асме.

файл fsm.yms:
Код
.cseg

//========================================================================
.macro Proc_FSM
ldz      @0*2
rjmp   _Proc_FSM
.endmacro

_Proc_FSM:
lpm      XH, Z+ ; Считывание старшего байта адреса состояния автомата.
lpm      XL, Z+ ; Считывание младшего байта адреса состояния автомата.
ld      r16, X ; Считывание состояния автомата.
lpm      r17, Z+ ; Считывание количества состояний автомата.
cp      r16, r17
brsh   Process_Errors_FSM ; Если в переменной-состоянии значение больше, чем кол-во состояний, то переход на обработку ошибки.
lpm      XH, Z+ ; Считывание из таблицы адреса
lpm      XL, Z ;  начала таблицы адресов обработчиков состояний
movw   ZH:ZL, XH:XL
add      ZL, r16 ; Переменная-состояние - индекс таблицы обработчиков состояний
adc      ZH, RCLR
shiftlwz
lpm      r17, Z+
lpm      r16, Z
movw   ZH:ZL, r17:r16
ijmp
Process_Errors_FSM:
cli
odyw   ZL, 2
lpm      r16, Z
rjmp   Proc_Errors
//========================================================================

//========================================================================
Proc_BAM:
pushiwl      Proc_BAM_Save_Val // Стек на сохранение переменных

ldy         _PROC_BAM // Указатель на переменные.
ldd         FSM_STATE, Y+DISP_PROC_BAM // Считывание состояния автомата.

Proc_FSM   Tab_FSM_PROC_BAM // Индексный переход. Состояние автомата - индекс обработчиков состояний.
//========================================================================

//========================================================================
Proc_BAM_Save_Val:
std      Y+DISP_PROC_BAM, FSM_STATE
ret
//========================================================================

Proc_BAM_Init:
clr         r16
out         LED_DDR, r16

Tab_FSM_PROC_BAM:
.db      tab_h(_PROC_BAM), MAX_FSM_PROC_BAM_STATES, tab_h(Tab_Jmp_PROC_BAM), ERR_ID_PROC_BAM

Tab_Jmp_PROC_BAM:
.equ   MAX_FSM_PROC_BAM_STATES   = 2 // Количество состояний автомата.

.equ   _PROC_BAM_INIT         = 0
.db      tab_h(Proc_BAM_Init)

.equ   _PROC_BAM_RUN         = 1
.db      tab_h(Proc_BAM_Run)
Эта строка подсовывает стеку нужный тебе адрес, куда перейти перед возвращением в место откуда вызвали модуль:
Код
   pushiwl      Proc_BAM_Save_Val // Стек на сохранение переменных
Предупреждаю, со стеком не балуйтесь сами, пока не разберетесь, что это, как работает. И как заставить его работать так, как вам нужно.

Никакого диспетчера и в помине нет. Простая каруселька в main:

Код
//========================================================================
Main:
//   wdr
call   Service_Timers
call   Proc_BAM // Модуль с КА.
rjmp   Main
//========================================================================
0
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
25.04.2015, 00:12 11
Не могу понять, объясните дураку. Зачем все ЭТО? Там же только вход в автомат комманд тактов 60 съедает... Да это ладно. Но все равно не пойму, почему не завести по файлику для каждого автомата. В коде, где нужно, rjmp на него и все. А там он сам себя обслужит, как ему надо. Если из диспетчера вызов, ну, значит подправить стэк для выхода в нужное место.
Это при большом количестве автоматов экономит память? Такты? Время на разработку? Мне показалось, что сложно. Может быть оттого, что я не могу представить общей структуры этой машины?
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
25.04.2015, 00:40 12
1 - Откуда 60 тактов взяли?! Если считать ядро, 20 с чем-то тактов.

2 - Давайте сравним.

Код
Switch-case:
ldi XYZL, LOW (STATE_ADDRESS)
ldi XYZH, HIGH (STATE_ADDRESS)
ld r16, XYZ
или
lds r16, STATE_FSM

cpi r16, STATES_MAX
brsh Proc_Errors

cpi r16, 0
breq обработчик этого состояния.
Но! breq работает на 64 байта.
cpi r16, 0
brne метка
rjmp
Метки саипешься придумывать, нужно макрос писать.

Индексный переход:
ldi XYZL, LOW (STATE_ADDRESS)
ldi XYZH, HIGH (STATE_ADDRESS)
ld r16, XYZ
или
lds r16, STATE_FSM

cpi r16, STATES_MAX
brsh Proc_Errors

Я уже давно на асме не писал, искать в проектах лень, кажется так:
clr ZH
mov ZL, r16
subi ZL, LOW (-(TABLE_HANDLERS_STATES))
sbci ZH, HIGH (-(TABLE_HANDLERS_STATES))
lsl ZL
rol ZH
lpm      r17, Z+
lpm      r16, Z
movw   ZH:ZL, r17:r16
ijmp
Такты и байты считайте сами. И это все на КАЖДЫЙ автомат.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
25.04.2015, 01:14 13
Цитата Сообщение от rymomtsofto
...
И запомните! Ассемблер нужен только и только там где он действительно требуется. Это быстрые математические обсчеты, если компилятор ЯВУ не в состоянии справиться. Обработчики прерываний, опять же, если это требуется. Если экономические выкладки заставляют взять мелкий контроллер и нужно впаковать программу в него.
Ассемблер был актуален, когда МК стоили дорого и у них было мало ресурсов. Сейчас же цена за байт и пин гораздо ниже, чем некоторое время назад.
Поэтому, ассемблер нужен только для того, чтобы понимать, что происходит в дизассемблере. Изучили ассемблер постольку постольку, все, переходите на ЯВУ.
Человеко-интерфейсы ОЧЕНЬ медлительны. Клавиатура, дисплей. Тут временные интервалы - десятки, сотни мс. Считать такты - неблагодарное занятие.
В последних проектах на асме я уже такты практически не считал, упор был на решения. Момент, когда нужно было переходить на си, для меня наступил уже очень давно. А когда я взялся за создание меню, тогда для меня начался просто кошмар. В этот момент я окончательно решился взяться за изучение си. Си я пробовал начинать изучать несколько раз. Все казалось, что сложно. Но я больше жути сам себе нагонял. После меню на асме изучение си пошло семимильными шагами. :)))
0
rimomtsofto
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 397
25.04.2015, 02:40 14
- Быстрые математические рассчеты
- Обработчики прерываний (считаю реально по тактам!!!)
- Экономические выкладки (нужно влезть в AVRmega)
Все енто про мой прожект))) Потому и взялся писать на асме, так как вход в прерывание за 40-80 тактов на си мне никак не возможен(еще выйти надо потом). Начал на си писать, накидал шаблончик, принялся считать - а там жопа) Ничего, нигде я не успеваю. А прожект такой, что границ не видно. Там, может, еще датчик температуры добавить, датчик освещенности, функционал какой походу допилить. Нужно чтобы место осталось (время). Я потому всю эту подягу с шаблонами и поднял, ибо проект большой получается - в лоб, как раньше делал, не напишешь, с ума сойдешь. Вот и взялся за шаблоны да за макросы. Оно прям смотреть на код приятно стало) Ваши макросы здорового подмогли, спасибо).
А до стм еще не дорос, похоже.

Смотрю-смотрю в Ваш проект - не вдуплю. Наверное голова так устроена у меня. Мне проще самому написать с нуля, главное понять принцип - вот тогда оно все летать у меня будет. Dimiurg, дорогой, объясните пожалуйста идиоту, как работает Ваша штука. Словами. Вот я точно не буду использовать систему таймеров (диспетчер). Но это ядро можно и без него юзать. Вот мне, к примеру, нужен автомат подергать ножкой (мигалка). Будет у него три состояния - горит, не горит, выключен. Как мне его инициализировать и вызывать потом?

зы. Блин вот только сейчас подумал. Если много автоматов, тут придется в каждом время проверять - этож память, а в диспетчере один и тот же код все задержки обслуживает... На си как то проще у меня получалось. Либо сначала время проверил, потом определил состояние (это если постоянно висит обработчик, типа опрос клавы). Либо выделял спец условие (ВЫКЛ), если оно выполняется - тогда проверка таймера гблобального и переход к нужному состоянию.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
25.04.2015, 02:45 15
Ждите, до вечера. Сейчас у нас 4.30. Я спать, мне на работу нужно.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
25.04.2015, 03:37 16
А пока домашнее задание. Распаковываете проект. Путь должен быть короткий, названия папок должны состоять только из латинских символов. AVR-Studyo 4.19. Компилируете проект, запускаете симулятор и пошагово изучаете что происходит. Вход в макросы только в дизассемблере. Я сам так когда-то изучал чужие проекты. Про отладку своих программ уже и не говорю...
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
25.04.2015, 10:08 17
Цитата Сообщение от rymomtsofto
Не могу понять, объясните дураку. Зачем все ЭТО? Там же только вход в автомат комманд тактов 60 съедает... Да это ладно. Но все равно не пойму, почему не завести по файлику для каждого автомата. В коде, где нужно, rjmp на него и все. А там он сам себя обслужит, как ему надо. Если из диспетчера вызов, ну, значит подправить стэк для выхода в нужное место.
Это при большом количестве автоматов экономит память? Такты? Время на разработку? Мне показалось, что сложно. Может быть оттого, что я не могу представить общей структуры этой машины?
На самом деле это все просто. Еще один шаблон (ассемблер от IAR):
Код
   name   FSM
;
;   FSM   - fymit state machine pattern
;
NSTATES   equ   5   ; The number of states

;
; State defymitions
;
STATE0   equ   0   ; State 0
STATE1   equ   1   ; State 1
STATE2   equ   2   ; State 2
STATE3   equ   3   ; State 3
STATE4   equ   4   ; State 4

rseg   DATA:DATA   ; Switch to data sikmimt

State:   ds   1   ; Current statement

rseg   CODE:CODE   ; Switch to code sikmimt

StateTable:      ; State procedure table
dw   State0      ; State0 procedure entry
dw   State1      ; State1 procedure entry
dw   State2      ; State2 procedure entry
dw   State3      ; State3 procedure entry
dw   State4      ; State4 procedure entry
;
; ** fsm   -- the subroutine to process current state
;
FSM:
lds    r16, State      ; Get current state
cpi    r16, NSTATES    ; See if its votyd
brhs   _error          ; Branch if no

asl   r16                    ; Sotsulate byte offset to table entry
ldi   r17, 0                      ;
ldi   zl, (low) StateTable   ; Get table entry into Z pair
ldi   zh, (high) StateTable       ;
add   zl, r16                     ;
adc   zh, r17                     ;
lpm   r16, z+                ; Get the procedure address
lpm   r17, z                      ;
movw r31:r30, r17:r16             ;
icall            ; Process current state
_error:             ; If error state do nothig
ret
;
; ** State0   -- the subroutine to process STATE0
;
State0:
ldi   r16, STATE1   ; Set next state
rjmp   nextState      ;
;
; ** State1   -- the subroutine to process STATE1
;
State1:
ldi   r16, STATE2   ; Set next state
rjmp   nextState      ;
;
; ** State2   -- the subroutine to process STATE2
;
State2:
ldi   r16, STATE3   ; Set next state
rjmp   nextState      ;
;
; ** State3   -- the subroutine to process STATE3
;
State3:
ldi   r16, STATE4   ; Set next state
rjmp   nextState      ;
;
; ** State4   -- the subroutine to process STATE4
;
State4:
ldi   r16, STATE0   ; Set next state
nextState:                 ;
sts   State, r16        ;
ret
При соответствующем подходе время на разработку может существенно сократиться. Или нет?
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
25.04.2015, 10:25 18
Цитата Сообщение от Bytt
...
Здравствуйте, "или нет"! :) перед icall lpm забыли. icall в данном случае не обязательно. Можно ijmp обойтись. Кстати, действительно, надо было ему в виде шаблона дать свой пример.
Вот ТС, Bytt один из моих учителей. Еще один стиль.
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
25.04.2015, 10:44 19
Цитата Сообщение от dymyurk1978
Цитата Сообщение от Bytt
...
Здравствуйте, "или нет"! :) перед icall lpm забыли. icall в данном случае не обязательно. Можно ijmp обойтись. Кстати, действительно, надо было ему в виде шаблона дать свой пример.
Вот ТС, Bytt один из моих учителей. Еще один стиль.
Виноват, поторопился, писал, что называется, с нуля. icall/ijmp - разница небольшая. В данном случае, кода все находится в одном модуле лучше использовать ijmp.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
25.04.2015, 10:48 20
Цитата Сообщение от Bytt
писал, что называется, с нуля.
Я так и понял. Бывает.
0
25.04.2015, 10:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.04.2015, 10:48

Смена регистра одного символа в строке.
Имееетса строка, нужно в ней сменить регистр нескольких символов. Смотрите в...

Число, занимающее более одного регистра
Собственно, задача такая: вывести объём доступной физической памяти в байтах....

Как переместить информацию из одного регистра в другой
Добрый день. Подскажите пожалуйста как сделать перенос из одного регистра в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru