И вроде на виду и "не приметны"...
Ассемблер (ASM) для AVR в вопросах и ответах
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Последние три позиции в functions...
И вроде на виду и "не приметны"...

И вроде на виду и "не приметны"...
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ноль на конце хорошь тогда, когда DB-шка не включает его. А ведь она может включать его. Отсюда мораль: найти у DB-шки конец надо другим способом.
Предполагаю так:
Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.
С AVRASM у меня все плохо, т.к linux
Предполагаю так:
Код: Выделить всё
read_loop:
ldi counter, 2*(endstring-string)
ldi ZL, low(2*string)
ldi ZH, high(2*string)
again:
lpm temp, Z+
rcall something
dec counter
tst counter
breq exit
rjmp again
С AVRASM у меня все плохо, т.к linux
-
С.Н.
- Потрогал лапой паяльник
- Сообщения: 307
- Зарегистрирован: Пн окт 26, 2020 08:37:51
- Откуда: г.Волгоград
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="Shuspano",url="/forum/viewtopic.php?p=4346131#p4346131"]Ноль на конце хорошь тогда, когда DB-шка не включает его. А ведь она может включать его. Отсюда мораль: найти у DB-шки конец надо другим способом.
.....Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.
С AVRASM у меня все плохо, т.к linux[/uquote]
А чем мой код то не понравился?
Вы думаете компилятор в конец строки какой то другой НОЛЬ подставит? Да, будет два ноля, но программа то все равно на первый сработает.
Причину "не работы" Вашей программы тяжело обнаружить не имея представления кто заполняет string и куда потом он идет. Ну на первый взгляд - Ваш регистр counter всегда ноль по выходу из Вашего цикла.
Присмотритесь к своей задаче и выберите себе один из форматов string - или "0 terminated" или (устаревший)с длиной строки в первом байте строки.
.....Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.
С AVRASM у меня все плохо, т.к linux[/uquote]
А чем мой код то не понравился?
Вы думаете компилятор в конец строки какой то другой НОЛЬ подставит? Да, будет два ноля, но программа то все равно на первый сработает.
Причину "не работы" Вашей программы тяжело обнаружить не имея представления кто заполняет string и куда потом он идет. Ну на первый взгляд - Ваш регистр counter всегда ноль по выходу из Вашего цикла.
Присмотритесь к своей задаче и выберите себе один из форматов string - или "0 terminated" или (устаревший)с длиной строки в первом байте строки.
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
- Starichok51
- Модератор
- Сообщения: 19054
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
tst counter - лишняя команда. после декремента уже тест сделан.Shuspano писал(а):dec counter
dec counter
tst counter
breq exit
rjmp again
и должно быть так:
dec counter
brne again
exit:
то есть, вместо пяти твоих строк нужно всего 2 строки.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
При текстовой строке, содержащей коды символов ASCII нужно только начальный адрес да контроль считанных данных на код 0х00.
Память читаем побайтово от начального адреса до встречи кода 0х00.
Или ищем иной код, используемый в качестве стопового, если это не символьная строка, а бинарник.

Вопрос резервирования места под строку актуален только для ОЗУ (или ЕЕПРОМ).

Память читаем побайтово от начального адреса до встречи кода 0х00.
Или ищем иной код, используемый в качестве стопового, если это не символьная строка, а бинарник.
Вопрос резервирования места под строку актуален только для ОЗУ (или ЕЕПРОМ).
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Практикую ставить метки в начале и в конце таблицы. К примеру
С наступающим...
Код: Выделить всё
read_loop:
ldi ZL,low(2*TBI) ;string)
ldi ZH,high(2*TBI) ;string)
again:
lpm R0, Z
rcall something
CPI ZL,LOW(2*TBI_END)
BRLO AGAIN
EXIT:
RJMP PC
something:
ST Z+,R0
RET
;*****
.org $100
TBI:
.DB $3F,$06 ; 0,1 Кодирования индикатора
.DB $5B,$4F ; 2,3
.DB $66,$6D ; 4,5
.DB $7D,$07 ; 6,7
.DB $7F,$6F ; 8,9
.DB $00,$00 ; гашение незначащего нуля
TBI_END:
;************************************************
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="akl",url="/forum/viewtopic.php?p=4346287#p4346287"]С наступающим...[/uquote]Спасибо 
Ну раз моё сообщение первое в этом году
, то ползвольте сначала всех поздравить 
С новым 2023-м годом уважаемые форумчане!
Пишу вот по какому поводу.. Вобщем интересная ситуация обнаружилась.
Сейчас пишу код, расчётов много, много загрузок тех или иных данных. Данные от 8-ми до 24 бит нужно грузить в три регистра, и если данные 8 или 16 бит, то старшие регистры очищаются естественно..
На этом фоне вопрос по оформлению кода встал ребром
Сначала грузил типа: в различных вариациях.
Потом после недолгих экспериментов пришёл к такому варианту: причём вместо Var1 может быть любое значение до 32 бит (но потребуется 4-й регистр) Код конечно стал на много симпатичнее и нагляднее.
Но самое интересное, что во всей документации по авр асму, которой располагаю (от атмел и микрочип), ни где в функциях не нашёл "BYTE1", хотя написано что "BYTE2" и "HIGH" дублируют друг друга.. Может конечно в каких то старых мануалах есть.
как то так ..
Ну раз моё сообщение первое в этом году
С новым 2023-м годом уважаемые форумчане!
Пишу вот по какому поводу.. Вобщем интересная ситуация обнаружилась.
Сейчас пишу код, расчётов много, много загрузок тех или иных данных. Данные от 8-ми до 24 бит нужно грузить в три регистра, и если данные 8 или 16 бит, то старшие регистры очищаются естественно..
На этом фоне вопрос по оформлению кода встал ребром
Сначала грузил типа:
Код: Выделить всё
.set Var1 = 0x6EF5
ldi R16, low (Var1)
ldi R17, high (Var1)
clr R18Потом после недолгих экспериментов пришёл к такому варианту:
Код: Выделить всё
.set Var1 = 0x28
ldi R20, BYTE1 (Var1)
ldi R21, BYTE2 (Var1)
ldi R22, BYTE3 (Var1)Но самое интересное, что во всей документации по авр асму, которой располагаю (от атмел и микрочип), ни где в функциях не нашёл "BYTE1", хотя написано что "BYTE2" и "HIGH" дублируют друг друга.. Может конечно в каких то старых мануалах есть.
как то так ..
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Все прекрасно описано еще для avrsam2 для аврстудио4 (правда мой экземпляр уже в редакции от микрощипа)
смотреть страницу33...
или тот же встроенный help -> avr tools user guide -> avr assembler -> user's guide -> expressions (для авр студио 4.19)
За byte1 видимо просто не сочли нужным делать описание его эквивалента low.
Кстати... есть и альтернатива:

или тот же встроенный help -> avr tools user guide -> avr assembler -> user's guide -> expressions (для авр студио 4.19)
За byte1 видимо просто не сочли нужным делать описание его эквивалента low.
Кстати... есть и альтернатива:
Код: Выделить всё
.set tests = 0x4567af
ldi r16,low(tests)
ldi r17,low(tests>>8)
ldi r18,low(tests>>16)Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ага, и по этому пришлось догадываться по смыслуBOB51 писал(а):За byte1 видимо просто не сочли нужным делать описание его эквивалента low.
Я кстати тем же документом от микрочипа пользовался.
Оо.. А за это спасибо. Тут можно больше 32 бит данных загрузить.BOB51 писал(а):Кстати... есть и альтернатива:
Код:
.set tests = 0x4567af
ldi r16,low(tests)
ldi r17,low(tests>>8)
ldi r18,low(tests>>16)
Добавлено after 56 minutes 14 seconds:
[uquote="shonty",url="/forum/viewtopic.php?p=4394904#p4394904"]Ага, и по этому пришлось догадываться по смыслу
п 57.2., стр. 90, (Atmel-0856L-AVR-Instruction-Set-Manual_Other-11/2016)
Но кстати я как то BYTE1,2,3.. лучше воспринимаю, чем low/high. И код ровнее
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="shonty",url="/forum/viewtopic.php?p=4394904#p4394904"]...Тут можно больше 32 бит данных загрузить...[/uquote]Касательно студии, поддерживающей 32-битные значения, не получится. Я не смог выразить константу, кроме как прямым занесением
Буду признателен тому, кто знает как это делается.
Код: Выделить всё
.equ VAR =1000000000000 ;E8 D4A5 1000Re: Ассемблер (ASM) для AVR в вопросах и ответах
В смысле? Только сейчас попробовал. Собирается без ошибок.akl писал(а):Касательно студии, поддерживающей 32-битные значения, не получится.
Студия 4.19, но в ней только собираю, а код пишу в стороннем редакторе.
Код: Выделить всё
.equ var = 999999999999999999999999999999999999999
ldi R16, low(var)
ldi R17, low(var>>8)
ldi R18, low(var>>16)
ldi R19, low(var>>24)
ldi R20, low(var>>32)
ldi R21, low(var>>40)
ldi R22, low(var>>48)
ldi R23, low(var>>56)
ldi R24, low(var>>64)Добавлено after 41 minute 51 second:
Хм.. да, действительно, больше 32 бит не получится.
Сейчас прогнал этот код, с выводом на дисплей.
Код: Выделить всё
.equ var = 77777777777777
ldi R16, low(var)
ldi R17, low(var>>8)
ldi R18, low(var>>16)
ldi R19, low(var>>24)
ldi R20, low(var>>32)
ldi R21, low(var>>40)
ldi R22, low(var>>48)
ldi R23, low(var>>56)
ldi R24, low(var>>64)
ldi R24, low(var>>72)
ldi YL,low (Result+9) ;
ldi YH,high (Result+9) ;
st Y, R16
st -Y, R17
st -Y, R18
st -Y, R19
st -Y, R20
st -Y, R21
st -Y, R22
st -Y, R23
st -Y, R24
st -Y, R25
а должно быть 46 BD 0C D0 DC 71
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Код: Выделить всё
;.equ var = 999999999999999999999999999999999999999; калькулятор XP-винды с этим числом не справился, поэтому урезал до
.equ var = 9999999999999999999;8AC7230489E7FFFF
.CSEG
TEST:
ldi R16, low(var)
ldi R17, low(var>>8)
ldi R18, low(var>>16)
ldi R19, low(var>>24)
ldi R20, low(var>>32)
ldi R21, low(var>>40)
ldi R22, low(var>>48)
ldi R23, low(var>>56)
ldi R24, low(var>>64)
RJMP TEST
.EXIT
Re: Ассемблер (ASM) для AVR в вопросах и ответах
ДЫК....
Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"

Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Тут дело больше не в том, что бы преодолеть 4-х байтовый порог, а найти способ написания кода, что бы более менее воспринимался интуитивно.
Я на TFT дисплеи "подсел". Там, что бы задать координаты поля, нужно отправить 8 байт. Долго я не мог найти интуитивно понятный вариант. Пробовал и через макросы и через массивы под .db, но всё не то..
Вот только недавно попробовал использовать .dw, на нём и остановлюсь.
Но .dw имеет свои особенности, связанные с 16-ти битной организацией памяти. По этому в подпрограмме обработки есть небольшие заморочки
Хотя ни по циклам, ни по коду за рамки дозволенного не вышла. Ещё и регистры экономятся.
Теперь запись стала выглядеть примерно так:
Set_str_1_tab: .DW 3, 319, 20, 20+23
Смотрю и понимаю в каком углу дисплея это поле находится
А до этого постоянно в калькулятор приходилось нырять, что бы перегнать в такое: 0x00, 0x03, 0x01, 0x3F, 0x00, 0x14, 0x00, 0x2B
ну или типа.
PS Тут ещё дело в значениях выше 0xff. Можно конечно в десятичном виде записывать: low(319), high(319), но это всё равно не изящно
Я на TFT дисплеи "подсел". Там, что бы задать координаты поля, нужно отправить 8 байт. Долго я не мог найти интуитивно понятный вариант. Пробовал и через макросы и через массивы под .db, но всё не то..
Вот только недавно попробовал использовать .dw, на нём и остановлюсь.
Но .dw имеет свои особенности, связанные с 16-ти битной организацией памяти. По этому в подпрограмме обработки есть небольшие заморочки
Теперь запись стала выглядеть примерно так:
Set_str_1_tab: .DW 3, 319, 20, 20+23
Смотрю и понимаю в каком углу дисплея это поле находится
А до этого постоянно в калькулятор приходилось нырять, что бы перегнать в такое: 0x00, 0x03, 0x01, 0x3F, 0x00, 0x14, 0x00, 0x2B
PS Тут ещё дело в значениях выше 0xff. Можно конечно в десятичном виде записывать: low(319), high(319), но это всё равно не изящно
- ДядяВован
- Вымогатель припоя
- Сообщения: 500
- Зарегистрирован: Вс окт 25, 2020 22:13:25
- Откуда: Смоленск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="Shuspano",url="/forum/viewtopic.php?p=4346131#p4346131"]С AVRASM у меня все плохо, т.к linux[/uquote]
gavrasm использую в linux, плюс avr_sim от того же автора.
gavrasm использую в linux, плюс avr_sim от того же автора.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="BOB51",url="/forum/viewtopic.php?p=4395088#p4395088"]ДЫК....
Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"
[/uquote]
4 байта – маловато будет. В, условно говоря, хорошем ассемблере, в котором сейчас работаю, размер переменных до 8 байт. Работать намного удобней. И команды есть удобные.
Например, чтобы в примере shonty отправить через USART массив Set_str_1_tab, можно просто написать команду:
USART_Send_Array Set_str_1_tab Z
Z – указание, что в команде будет использоваться пара регистров Z.
Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"
4 байта – маловато будет. В, условно говоря, хорошем ассемблере, в котором сейчас работаю, размер переменных до 8 байт. Работать намного удобней. И команды есть удобные.
Например, чтобы в примере shonty отправить через USART массив Set_str_1_tab, можно просто написать команду:
USART_Send_Array Set_str_1_tab Z
Z – указание, что в команде будет использоваться пара регистров Z.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 545
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Ассемблер (ASM) для AVR в вопросах и ответах
AQ29, в ассемблере, какую обработку вы напишете, столько байт число и будет. Хоть 16. Хоть 32.
ПС. USART_Send_Array - не команда ассемблера, а макрос вашего алгоритм билдера, который асемблером называть не совсем корректно.
ПС. USART_Send_Array - не команда ассемблера, а макрос вашего алгоритм билдера, который асемблером называть не совсем корректно.
Белая и Пушистая
Я не ИИ, поэтому могу ошибаться.
Я не ИИ, поэтому могу ошибаться.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4480077#p4480077"]AQ29, в ассемблере, какую обработку вы напишете, столько байт число и будет. Хоть 16. Хоть 32.
ПС. USART_Send_Array - не команда ассемблера, а макрос вашего алгоритм билдера, который асемблером называть не совсем корректно.[/uquote]
У меня не алгоритм билдер (АБ). Он давно устарел и сейчас явно слаб.
Ясно, что в командах ассемблера можно сделать разную обработку. Но с переменными работать многократно удобней, ведь для них для основных операций есть встроенные макросы, которые возьмут рутину на себя.
Когда при расчёте по сложной формуле переменная превысила 8 байт, менял алгоритм расчёта, чтобы остаться в пределах 8 байт.
Я не писал, что USART_Send_Array – команда ассемблера, у меня она названо просто командой.
В АБ нет встроенных команд такого типа. В АБ придётся самому писать макросы для всех вариантов команды, а их много.
Приведена неполная команда. В полном представлении команды есть ещё необязательные параметры: начальный индекс, с которого начнётся посылка массива, и число посылаемых элементов.
Есть ещё параметр Wait. При полудуплексной передаче после посылки пакета нельзя сразу переходить к приёму, надо подождать передачи последнего байта. Параметр Wait это делает.
Можно также указать номер USART, ведь в некоторых МК есть несколько USART.
Самому писать макросы под все эти варианты – тяжкий труд, это что-то из программирования прошлого века.
А со встроенными командами всё проще, достаточно только набрать строчку команды.
Насчёт некорректности названия ассемблер согласен. В этом плане предварительно сделал замечание «условно говоря». Программа находится где-то между ассемблером и ЯВУ. К ассемблеру всё-таки ближе.
ПС. USART_Send_Array - не команда ассемблера, а макрос вашего алгоритм билдера, который асемблером называть не совсем корректно.[/uquote]
У меня не алгоритм билдер (АБ). Он давно устарел и сейчас явно слаб.
Ясно, что в командах ассемблера можно сделать разную обработку. Но с переменными работать многократно удобней, ведь для них для основных операций есть встроенные макросы, которые возьмут рутину на себя.
Когда при расчёте по сложной формуле переменная превысила 8 байт, менял алгоритм расчёта, чтобы остаться в пределах 8 байт.
Я не писал, что USART_Send_Array – команда ассемблера, у меня она названо просто командой.
В АБ нет встроенных команд такого типа. В АБ придётся самому писать макросы для всех вариантов команды, а их много.
Приведена неполная команда. В полном представлении команды есть ещё необязательные параметры: начальный индекс, с которого начнётся посылка массива, и число посылаемых элементов.
Есть ещё параметр Wait. При полудуплексной передаче после посылки пакета нельзя сразу переходить к приёму, надо подождать передачи последнего байта. Параметр Wait это делает.
Можно также указать номер USART, ведь в некоторых МК есть несколько USART.
Самому писать макросы под все эти варианты – тяжкий труд, это что-то из программирования прошлого века.
А со встроенными командами всё проще, достаточно только набрать строчку команды.
Насчёт некорректности названия ассемблер согласен. В этом плане предварительно сделал замечание «условно говоря». Программа находится где-то между ассемблером и ЯВУ. К ассемблеру всё-таки ближе.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Всем добрый день. Подскажите, как можно пробежаться по массиву, размещённому во флеш-памяти? Есть atmega8a. Написал такую программу, но она не работает
Во всех примерах рекомендуют записать в Z регистр адрес массива, сдвинутый влево, но gnu assembler, как оказалось, не умеет применять операторы умножения и сдвига к адресам меток. Похоже, это связано с особенностями линковщика (по крайней мере, так пишут тут https://stackoverflow.com/questions/184 ... binary-and). Поэтому я поступил прямолинейнее и просто сдвинул ZL и ZH влево, а потом увеличил ZH, чтобы вернуть бит, потерянный при сдвиге. Но программа всё равно не работает и просто пишет 0xff в PORTC. Подскажите, в чём может быть ошибка?
Код: Выделить всё
#define __SFR_OFFSET 0
#include "avr/io.h"
/* Секция данных */
.section .data
table:
.byte 0b00000001, 0b00000010, 0b00000011
/* Секция кода */
/*
1 0x000(1) RESET External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset
2 0x001 INT0 External Interrupt Request 0
3 0x002 INT1 External Interrupt Request 1
4 0x003 TIMER2 COMP Timer/Counter2 Compare Match
5 0x004 TIMER2 OVF Timer/Counter2 Overflow
6 0x005 TIMER1 CAPT Timer/Counter1 Capture Event
7 0x006 TIMER1 COMPA Timer/Counter1 Compare Match A
8 0x007 TIMER1 COMPB Timer/Counter1 Compare Match B
9 0x008 TIMER1 OVF Timer/Counter1 Overflow
10 0x009 TIMER0 OVF Timer/Counter0 Overflow
11 0x00A SPI, STC Serial Transfer Complete
12 0x00B USART, RXC USART, Rx Complete
13 0x00C USART, UDRE USART Data Register Empty
14 0x00D USART, TXC USART, Tx Complete
15 0x00E ADC ADC Conversion Complete
16 0x00F EE_RDY EEPROM Ready
17 0x010 ANA_COMP Analog Comparator
18 0x011 TWI Two-wire Serial Interface
19 0x012 SPM_RDY Store Program Memory Ready
*/
.section .text
.org 0x0000
rjmp RESET_vect
reti ; INT0
reti ; INT1
reti ; TIMER2_COMP
reti ; TIMER2_OVF
reti ; TIMER1_CAPT
reti ; TIMER1_COMPA
reti ; TIMER1_COMPB
reti ; TIMER1_OVF
reti ; TIMER0_OVF
reti ; SPI_STC
reti ; USART_RXC
reti ; USART_UDRE
reti ; USART_TXC
reti ; ADC
reti ; EE_RDY
reti ; ANA_COMP
reti ; TWI
reti ; SPM_RDY
RESET_vect:
ldi r16, RAMEND & 0xff
out SPL, r16
ldi r16, RAMEND >> 8
out SPH, r16
ldi r16, 0b00111111
out DDRC, r16
ldi r16, 0b00000000
sei
_main:
out PORTC, r16
ldi ZL, lo8(table)
ldi ZH, hi8(table)
lsl ZH
lsl ZL
brcc _set_index
inc ZH
_set_index:
ldi r17, 3
_loop:
lpm r0, Z+
out PORTC, r0
dec r17
cpi r17, 0x00
brne _loop
rjmp _main
Re: Ассемблер (ASM) для AVR в вопросах и ответах
[uquote="chtulhu",url="/forum/viewtopic.php?p=4481822#p4481822"]просто сдвинул ZL и ZH влево,[/uquote]
А если так попробовать:
lsl ZL
rol ZH
Хз какой там синтаксис у GNU, в студии 4 обычно так пишу:
LDI ZH, High(Code_Table*2) ; адрес кодовой таблицы
LDI ZL, Low(Code_Table*2) ;
lpm ; данные в регистре 0
А если так попробовать:
lsl ZL
rol ZH
Хз какой там синтаксис у GNU, в студии 4 обычно так пишу:
LDI ZH, High(Code_Table*2) ; адрес кодовой таблицы
LDI ZL, Low(Code_Table*2) ;
lpm ; данные в регистре 0


