Страница 94 из 400
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт июл 21, 2011 14:13:51
john_rise
avreal писал(а):
Код: Выделить всё
mov XL,indx
clr XH
subi XL, low( -table)
sbci XH, high( -table)
По длине как второй вариант, но не требует постоянно выделенного доп. регистра.
По сравнению с первым вариантом и короче, и даже временно не требует доп регистра.
Да я в курсе минусования отрицательной константы, выдел ранее что компиляторы так делают.
Скриншот моего кода в атаче, только формат записи у меня несколько иной.
Спасибо за внимание и ответы!
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 15:02:25
avreal
1) Ну тогда в Вашем замечании нужно было сказать ещё, что писать надо не
XL и
XH, а
ZL и
ZH

Так как для того доступа, который в принципе возможно осуществить через
X, ни в одном из ассемблеров ничего делить не надо.
2) У IAR-овского и у GCC-шного ассемблеров и флеш адресуется побайтово, что даёт возможность плотнее заполнять флеш данными (строки и структуры могут действительно занимать нечётное число байт и могут начинаться с середины слова). У них наоборот -- для получения адреса данных делать ничего не надо, а под IJMP/ICALL надо на два
делить.
3) Да, спасибо за ссылку на обсуждение мной же приведённого кода

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 15:38:23
john_rise
avreal, а можно поподробнее как адресоваться к байту а не к слову во flash?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 16:37:00
avreal
У IAR и GCC в самих ассемблерах байтовая адресация.
И в ORG, и при использовании метки сам ассемблер пользуется байтовой адресацией.
Т.е.
Код: Выделить всё
.org 200 ; начинаем с СОТОГО слова.
foo: .byte 1
.byte 2,3
moo: .byte 3,4,5
Во флеше с сотого слова
foo имеет значение 200, moo имеет значение 203.
В листинге так полусловами и покажет
Код: Выделить всё
1 .text
2 0000 0000 0000 .org 200
2 0000 0000
2 0000 0000
2 0000 0000
2 0000 0000
3 .global foo
4 .global moo
5 foo:
6 00c8 0102 03 .byte 1,2,3
7 moo:
8 00cb 0304 05 .byte 3,4,5
9 .end
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 18:08:23
john_rise
К сожалению не совсем понял. Насколько я знаю каждый последующий адрес памяти программ содержит по 2 байта (16 bit word). Значит шагать можно только по 2 байта, задав адрес имеем в доступе младший байт слова, для доступа к старшему адресу нужно сместиться:
lpm Z+
или:
adiw Z,0x01
lpm Z
Неужели я могу задать сразу адрес старшего байта слова? - и считать его без дополнительного действия-смещения?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 19:09:58
ChipKiller
john_rise писал(а):... Значит шагать можно только по 2 байта....
не путайте выполнение инструкций и адресацию к памяти программ - обратиться к любому байту ничто не мешает...
john_rise писал(а):Неужели я могу задать сразу адрес старшего байта слова...
.. это определяется содержимым младшего бита регистра ZL
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 21:52:50
avreal
А вот кстати у меня есть неплохой примерчик того, как адрес кода первращается на ходу в адрес данных и назад.
Располагаем строку для печати на терминал прямо в коде, сразу за вызовом подпрограммы печати (эх, где мои JSR R5, addr)
Код: Выделить всё
; этот вызов и следующие две строки удобно завернуть в макрос,
; но тут так для ясности написано развёрнуто
rcall printstr_с
.asciz "fooo" ; строка с завершющим нулём занимает 5 байт, поэтому нужно
.align 2 ; подравнять на границу 2 байт и только потом писать следующие команды
; после выполнения printstr_c вернёмся сюда!
nop ; пошли следующие команды
Вот так оно скомпилируется:
Код: Выделить всё
173 006c 00D0 rcall printstr_c
174 006e 666F 6F6F .asciz "fooo"
174 00 ; Это завершающий 0 от строки
175 0073 00 .align 2 ; а это дополнительный 0 для того, чтобы
176 0074 0000 nop ; следующая команда была с чётного (словного) адреса
Команда rcall помещает на стек арес следующей
команды. А у нас там
данные -- текст. Так что надо:
Код: Выделить всё
printstr_c:
pop r31 ; POP-нуть этот адрес *слова-команды* из стека в Z
pop r30
lsl r30 ; умножить на два -- получить адрес *байта-данных*
rol r31
rjmp pr_2
pr_1:
rcall putchar ; детали вывода символа нас сейчас не интересуют
pr_2:
lpm r16, Z+ ; читаем байт и переходим к следующему *байтовому* адресу
tst r16
brne pr_1 ; если встретили завершающий 0 -- строка закночилась
adiw r30,1 ; округляем вверх до чётного числа *байтов*
lsr r31 ; и делим на два для возврата к *словам-командам*
ror r30 ; (тот же align)
ijmp ; теперь делаем "возврат" в точку сразу за строкой в ПЗУ
Тут, кончечно, строки с чётным числом символов (нечётным числом байтов вместе с 0-терминатором) занимают лишний байт по сравнению с помещением всех строк в отдельню секцию с байтовым выравниванием, но даже в этом случае где-то после шестой строки будем иметь выигрыш в три байта на вызов по сравнению с
Код: Выделить всё
ldi ZL, low (string) ; вот эти четыре байта
ldi ZH, high (string) ; будут экономиться на каждом вызове
rcall putstr_з
В худшем случае один байт будет пропадать на align и экономия в три байта. В лучшем -- экономия 4 байта. Но сама подпрограмма вывода с доставанием адреса из стека и манипуляциями с ним длиннее, поэтому прибыль пойдет где-то с пятого-шестого вызова

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 23, 2011 22:13:50
avreal
Оффтопически-историческая справка по поводу "где мои JSR R5, addr"
У "хита всех времён и народов" PDP-11 не было команды вызова подпрограммы CALL в тако виде, как у AVR, PIC, MCS51 и прочих. К тому, что у неё было, ближе всех ARM-овская команда BL.
CALL addr у PDP-11 была просто синонимом ассемблера к команде JSR PC, addr (о вариациях задания addr сейчас не будем).
JSR REG, ADDR
Jump to SubRoutine работала так:
Затолкать в стек регистр REG (а не адрес возврата)
Поместить в REG адрес возврата
Поместить в счётчик команд адрес подпрограммы (последние две строки у ARM полчили имя BL == Branch and Link)
В результате приведенное выше выглядело бы так
Код: Выделить всё
jsr r5, printstr_c
.asciiz "fooo"
.align
...
printstr_c:
; А адрес-то "возврата", т.е. строки, у нас уже в R5 !
movb (R5)+, R0 ; берем байт-символ по адресу в R5 и увеличиваем R5 на 1.
bne done ; mov устанавливает флаги -- проверка на 0 уже сделана
call putchar ; то же самое, что JSR PC, putchar, где PC aka R7 -- счётчик команд
jmp printstr_c
done:
rts r5 ; ReTurn from Subroutine
RTS REG делает обратное действие -- заносит REG в счётчик команд и восстанавливает REG из стека.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс июл 24, 2011 22:16:34
IfoR
avreal, вау! Надо запомнить эту магию!

Спасибо, сэнсэй!
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн июл 25, 2011 11:52:03
SII
avreal писал(а):Оффтопически-историческая справка по поводу "где мои JSR R5, addr"
У "хита всех времён и народов" PDP-11 не было команды вызова подпрограммы CALL в тако виде, как у AVR, PIC, MCS51 и прочих. К тому, что у неё было, ближе всех ARM-овская команда BL.
Не совсем верно. Во-первых, JSR на PDP-11 могла работать полностью аналогично привычному CALLу, достаточно было записать её в виде: JSR PC, адрес -- и она пихила в стек именно PC, т.е. адрес возврата. Во-вторых, ARMовская BL является точной копией команды перехода с возвратом мэйнфреймов IBM (System/360, 370 и т.д.): у тех стека не было в принципе, и адрес возврата запоминался в регистре. У ARMа стек есть, но сохранять в нём адрес возврата надо ручками.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн июл 25, 2011 13:11:38
avreal
SII писал(а):Не совсем верно. Во-первых, JSR на PDP-11 могла работать полностью аналогично привычному CALLу, достаточно было записать её в виде: JSR PC, адрес -- и она пихила в стек именно PC, т.е. адрес возврата. Во-вторых, ARMовская BL является точной копией команды перехода с возвратом мэйнфреймов IBM (System/360, 370 и т.д.): у тех стека не было в принципе, и адрес возврата запоминался в регистре. У ARMа стек есть, но сохранять в нём адрес возврата надо ручками.
Вы читаете всё, или только то, на что можете хорошо ответить?
avreal писал(а):У "хита всех времён и народов" PDP-11 не было команды вызова подпрограммы CALL в тако виде, как у AVR, PIC, MCS51 и прочих. К тому, что у неё было, ближе всех ARM-овская команда BL.
CALL addr у PDP-11 была просто синонимом ассемблера к команде JSR PC, addr
Я сказал и про JSR PC, ... -- а дальше из описания действий понятно, что при этом она сохраняа на стеке и восстанавливала отутда тот REG, который PC. И про то, что мнемоника ассемблера CALL была у PDP-11 -- как синоним к этой JSR PC,... .
И про армовский BL я не говорил, что он есть
точной копией JSR у PDP-11, просто похожи в том, что адрес возврата в регистр заносится и даже уточнил в описании JSR какая часть соответствует.
А то, что я про /360-ые не написал, так я и не собирался, так как не знаю

. Вышло "не совсем полно", а не "не совсем верно", но "совсем полно" это слишком много, я не претендую на такую энциклопедичность. Даже для "чуточку полнее" как минимум ещё HP2100/М6000/СМ-2 придётся вспомнить с их отсутстием стека, но наличием JSR и удобно сделанной возможностью брать параметры из кода после вызова функции.
В любом случае и PDP-11-шный JSR, и ARM-овский BL гораздо удобнее для передачи константных параметров (не только строк), чем то, что приходится делать в AVR.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн июл 25, 2011 21:17:18
SII
avreal писал(а):Вы читаете всё, или только то, на что можете хорошо ответить?
А Вы всё, хоть малость с Вашим мнением/описанием не согласующееся, считаете личным наездом?
И про то, что мнемоника ассемблера CALL была у PDP-11 -- как синоним к этой JSR PC
А вот это уже прямая Ваша
ошибка. Такой
мнемоники ассемблера у PDP-11 не было -- была широко применявшаяся
макрокоманда, которая превращалась в JSR PC. Исходники RSX-11M в качестве доказательста выкладывать, или так поверите?
В любом случае и PDP-11-шный JSR, и ARM-овский BL гораздо удобнее для передачи константных параметров (не только строк), чем то, что приходится делать в AVR.
А вот в этом во мнениях сойдёмся

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт июл 26, 2011 09:18:53
avreal
SII писал(а):avreal писал(а):Вы читаете всё, или только то, на что можете хорошо ответить?
А Вы всё, хоть малость с Вашим мнением/описанием не согласующееся, считаете личным наездом?
Вполне возможно

Со стороны виднее.
SII писал(а):И про то, что мнемоника ассемблера CALL была у PDP-11 -- как синоним к этой JSR PC
А вот это уже прямая Ваша
ошибка. Такой
мнемоники ассемблера у PDP-11 не было -- была широко применявшаяся
макрокоманда, которая превращалась в JSR PC. Исходники RSX-11M в качестве доказательста выкладывать, или так поверите?
Нет, спасибо, не надо, это слишком весомый аргумент

Поверю и так.
Тем более, что для написания программ исходники ОС не нужны.
Только вот начисто не могу припомнить, чтобы для применения CALL приходилось использовать какие-то файлы макроописаний, а разницы между наглухо встроенным макросом и мнемоникой не вижу. Не роясь в исходниках MACRO-11 их не отличить.
Ну забыл так забыл...
Хотя рановато

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт июл 26, 2011 23:46:10
Steam
Доброе время суток!
вот макрос инициализации данных в ОЗУ:
Код: Выделить всё
; ===========
; Макрос инициализации == @0 - адрес, @1 - длина в байтах, @2 - значение для инициализации
; ===========
.macro dataInit
LDI ZL, Low(@0) ; загружаем адрес
LDI ZH, High(@0)
CLR R16 ; счетчик
LDI R17, @2
;cycle_dataInit:
ST Z+, R17
INC R16
CPI R16, @1
BRNE PC - 3
.endmacro
; ===========
собственно вопрос: на что можно заменить BRNE PC - 3? Слышал, что компилятор сам умеет создавать уникальные метки, но не нашёл как это делается.
Спасибо за внимание!
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт июл 26, 2011 23:59:50
IfoR
А я пробовал просто как обычно писать любую метку в макросе. После расстановки нескольких макросов прога нормально работала. Но это дело не так недавно было.

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср июл 27, 2011 00:18:24
Steam
И правда работает! Боялся попробовать... Спасибо!
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 30, 2011 19:25:22
Dako
Только начал изучать ассемблер и АВР. Ну и споткнулся на прерываниях таймера/счетчика1, всю голову уже сломал - не работает и всё тут. Подскажите пожалуйста, что не так? Программка мигает диодом по совпадения таймера1 с OCR1A
.device atmega8
.nolist
.include "D:\RomaAVR\m8def.inc"
.list
.def temp =r16
.def temp2 =r17
rjmp Init ;
reti ;
reti ;
reti ;
reti ;
reti ;
reti ;
rjmp tccomp ;
tccomp:
in temp,PinB ;
com temp ;
out PortB,temp ;
reti ;
Init:
ldi temp,LOW(RAMEND) ;
out SPL,temp ;
ldi temp,HIGH(RAMEND) ; Инициализирую стек
out SPH,temp ;
ser temp
out DDRB,temp ;
out DDRC,temp ;
out DDRD,temp ; Определяю порты
clr temp
out PortD,temp ;
out PortC,temp ;
ldi temp,0b00000101 ;
out PortB,temp ;
;ldi temp,0b11000000 ;
;out GICR,temp ;
;clr temp ; Разрешаю и конфигурирую внешние прерывания
;out MCUCR,temp ;
ldi temp,0b00001001 ; Конфигурирую Таймер/Счетчик1
out TCCR1B,temp ;
ldi temp,0b00010000 ; Разрешаю прерываение по сравнению А
out TIMSK,temp ;
ldi temp,0x03 ;
ldi temp2,0xD0 ; Задаю значения в регистры сравнения
out OCR1AH,temp ;
out OCR1AL,temp2 ;
sei ; Разрешаю прерывания
Start:
rjmp Start ;
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 30, 2011 20:54:15
Gudd-Head
Даже не знаю с чего начать...
В АВРСтудии прогоняли?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб июл 30, 2011 20:58:39
IfoR
Вы промахнулись строкой:
rjmp tccomp ;
она должна стоять на 7 месте, а не на 8.
А вообще, лучше использовать директивы .ORG
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн авг 01, 2011 16:44:36
vit007
EXT_INT0:
ldi Temp,1
sub Temp, Temp4
clr Temp4
reti
EXT_INT1:
inc Temp
cpi Temp,1
breq qwe
ldi Temp5,1
out PortD,Temp5
ldi Temp1,0
ldi Temp2,0
ldi Temp3,10
Loop: dec Temp1
brne Loop
dec Temp2
brne Loop
dec Temp3
brne Loop
ldi Temp5,0
out PortD,Temp5
rjmp r
qwe: ldi Temp4,1
r: clr Temp
reti
Здрасть, помогите сделать датчик на дверь...
по входу все хорошо, а вот обратно не хочет, т.е. когда второе прерывание срабатывает, соответственно за ним первое, но когда повторяешь действие выхода срабатывает, как вошел...
Это конечно на атмеге8, но хочется на тине85, но там всего одно внешнее прерывание...
Подскажите, как собрать единицу или ноль с порта (in...?)