Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Грызет канифоль
Аватара пользователя
Сообщения: 276
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Just_Fluffy писал(а):а если строка с нечетным количеством символов? И добита нулем в конце до четного ?
Оно само так делает :)

Код: Выделить всё

home/lester/AVR/avra-master/includes/m48def.inc(914) : PRAGMA directives currently ignored
asmtest.asm(31) : Warning : A .DB segment with an odd number of bytes is detected. A zero byte is added.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 555
Зарегистрирован: Ср июн 29, 2022 16:25:45

Сообщение Just_Fluffy »

Shuspano, да, студия умная. Но вопрос остается - как определить нечетную длину строки?
Белая и Пушистая
Я не ИИ, поэтому могу ошибаться.
Реклама
Это не хвост, это антенна
Сообщения: 1495
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Подсчитать число символов в строке, кроме нуля. Если младший байт 1, значит нечётное.
Контактная информация:
Потрогал лапой паяльник
Сообщения: 314
Зарегистрирован: Пн окт 26, 2020 08:37:51
Откуда: г.Волгоград

Сообщение С.Н. »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4345631#p4345631"]Shuspano, да, студия умная. Но вопрос остается - как определить нечетную длину строки?[/uquote]
Так, как говорит Demiurg. "В лоб" - программно. Сам так поступаю.

Код: Выделить всё

#define Text  "Ля-Ля-Ля"
.
.
.Macro	ldiw 
ldi 	@0L,low(@1)
ldi	@0H,High(@1)
.EndMacro
.
.
textptr: .db Text,'\0'	
.
.
ldiw Z,textptr*2
clr	r16
loop1:   
inc r16
lpm r17,Z+
tst r17
brne loop1
;            r16 - длина строки

Ну или совсем просто

ldi r16,STRLEN(Text)
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 555
Зарегистрирован: Ср июн 29, 2022 16:25:45

Сообщение Just_Fluffy »

Хе... "В лоб" там вообще не нужно знать конец строки, только начало. Но это только в Run-Time.
А на этапе компиляции, увы, только по дельте 2 меток, помноженной на 2. И принимать потом уже программные меры, что б не схавать лишний ноль.

С.Н.,
STRLEN(Text)
- простите, это что? Фишка препроцессора?
Каюсь, я уже достаточно давно перестала писать под АВР на асме... Хотя это был первый асм для МК, который изучала вместе с АВРками. Эхххх.. где моя любимая отладка 2313....
Белая и Пушистая
Я не ИИ, поэтому могу ошибаться.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

В avrasm2 такой директивы (strlen) нету...
Или макрос или чего-то из микрочипстудио...
:dont_know:
Реклама
Потрогал лапой паяльник
Сообщения: 314
Зарегистрирован: Пн окт 26, 2020 08:37:51
Откуда: г.Волгоград

Сообщение С.Н. »

[uquote="BOB51",url="/forum/viewtopic.php?p=4345819#p4345819"]В avrasm2 такой директивы (strlen) нету...
Или макрос или чего-то из микрочипстудио...
:dont_know:[/uquote]
Нет проблем. Сам как-то пропустил.
Стр. 33.
Я сначала проверил, прежде чем выкладывать версию.
Вложения
AVRASM2 Assembler Manual.pdf
(312.32 КБ) 156 скачиваний
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Последние три позиции в functions...
И вроде на виду и "не приметны"...
:?
Грызет канифоль
Аватара пользователя
Сообщения: 276
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Ноль на конце хорошь тогда, когда DB-шка не включает его. А ведь она может включать его. Отсюда мораль: найти у DB-шки конец надо другим способом.
Предполагаю так:

Код: Выделить всё

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
Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.

С AVRASM у меня все плохо, т.к linux
Потрогал лапой паяльник
Сообщения: 314
Зарегистрирован: Пн окт 26, 2020 08:37:51
Откуда: г.Волгоград

Сообщение С.Н. »

[uquote="Shuspano",url="/forum/viewtopic.php?p=4346131#p4346131"]Ноль на конце хорошь тогда, когда DB-шка не включает его. А ведь она может включать его. Отсюда мораль: найти у DB-шки конец надо другим способом.
.....Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.
С AVRASM у меня все плохо, т.к linux[/uquote]
А чем мой код то не понравился?
Вы думаете компилятор в конец строки какой то другой НОЛЬ подставит? Да, будет два ноля, но программа то все равно на первый сработает.
Причину "не работы" Вашей программы тяжело обнаружить не имея представления кто заполняет string и куда потом он идет. Ну на первый взгляд - Ваш регистр counter всегда ноль по выходу из Вашего цикла.
Присмотритесь к своей задаче и выберите себе один из форматов string - или "0 terminated" или (устаревший)с длиной строки в первом байте строки.
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
Модератор
Аватара пользователя
Сообщения: 19103
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

Shuspano писал(а):dec counter
dec counter
tst counter
breq exit
rjmp again
tst counter - лишняя команда. после декремента уже тест сделан.
и должно быть так:
dec counter
brne again
exit:

то есть, вместо пяти твоих строк нужно всего 2 строки.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

При текстовой строке, содержащей коды символов ASCII нужно только начальный адрес да контроль считанных данных на код 0х00.
Память читаем побайтово от начального адреса до встречи кода 0х00.
Или ищем иной код, используемый в качестве стопового, если это не символьная строка, а бинарник.
:roll:
Вопрос резервирования места под строку актуален только для ОЗУ (или ЕЕПРОМ).
8)
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Практикую ставить метки в начале и в конце таблицы. К примеру

Код: Выделить всё

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:
;************************************************
С наступающим...
Мучитель микросхем
Аватара пользователя
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Сообщение shonty »

[uquote="akl",url="/forum/viewtopic.php?p=4346287#p4346287"]С наступающим...[/uquote]Спасибо :)

Ну раз моё сообщение первое в этом году :), то ползвольте сначала всех поздравить :)
С новым 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)
причём вместо Var1 может быть любое значение до 32 бит (но потребуется 4-й регистр) Код конечно стал на много симпатичнее и нагляднее.

Но самое интересное, что во всей документации по авр асму, которой располагаю (от атмел и микрочип), ни где в функциях не нашёл "BYTE1", хотя написано что "BYTE2" и "HIGH" дублируют друг друга.. Может конечно в каких то старых мануалах есть. :dont_know:

как то так ..
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Все прекрасно описано еще для avrsam2 для аврстудио4 (правда мой экземпляр уже в редакции от микрощипа)
40001917A_AVR Assembler_User Guides.pdf
(312.32 КБ) 157 скачиваний
смотреть страницу33...
или тот же встроенный 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)
:beer:
Мучитель микросхем
Аватара пользователя
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Сообщение shonty »

BOB51 писал(а):За byte1 видимо просто не сочли нужным делать описание его эквивалента low.
Ага, и по этому пришлось догадываться по смыслу :)) у меня не так много фудаментальных знаний.
Я кстати тем же документом от микрочипа пользовался.
BOB51 писал(а):Кстати... есть и альтернатива:
Код:
.set tests = 0x4567af
ldi r16,low(tests)
ldi r17,low(tests>>8)
ldi r18,low(tests>>16)
Оо.. А за это спасибо. Тут можно больше 32 бит данных загрузить.
:beer:

Добавлено after 56 minutes 14 seconds:
[uquote="shonty",url="/forum/viewtopic.php?p=4394904#p4394904"]Ага, и по этому пришлось догадываться по смыслу :))...[/uquote] Ан нет, нашёл "BYTE1", в атмеловском "AVR Instruction Set Manual", вскользь упоминается всего в одном месте и то в примере.
п 57.2., стр. 90, (Atmel-0856L-AVR-Instruction-Set-Manual_Other-11/2016)

Но кстати я как то BYTE1,2,3.. лучше воспринимаю, чем low/high. И код ровнее :))
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

[uquote="shonty",url="/forum/viewtopic.php?p=4394904#p4394904"]...Тут можно больше 32 бит данных загрузить...[/uquote]Касательно студии, поддерживающей 32-битные значения, не получится. Я не смог выразить константу, кроме как прямым занесением

Код: Выделить всё

.equ	VAR	=1000000000000	;E8 D4A5 1000
Буду признателен тому, кто знает как это делается.
Мучитель микросхем
Аватара пользователя
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Сообщение shonty »

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)
PS что в R24 не проверял, но думаю, что именно 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
Младшие 32 бита выводит правильно, а дальше или нули или мусор из FF, в зависимости от константы.

Изображение

а должно быть 46 BD 0C D0 DC 71
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Код: Выделить всё

;.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
:dont_know: Ничего похожего на 0x8AC7230489E7FFFF моя студия не собирает. Жирным выделено правильная часть значения.
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

ДЫК....
Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"
:beer:
Ответить

Вернуться в «AVR»