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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
john_rise
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн дек 17, 2007 13:15:43

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

Сообщение john_rise »

avreal писал(а):

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

    mov XL,indx
    clr XH
    subi XL, low( -table)
    sbci XH, high( -table)
По длине как второй вариант, но не требует постоянно выделенного доп. регистра.
По сравнению с первым вариантом и короче, и даже временно не требует доп регистра.


Да я в курсе минусования отрицательной константы, выдел ранее что компиляторы так делают.
Скриншот моего кода в атаче, только формат записи у меня несколько иной.

MEND.gif
(46.44 КБ) 586 скачиваний


Спасибо за внимание и ответы!
Боишся - не делай. Делаешь - не бойся.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

IM1 писал(а):avreal , полностью согласен, только писать надо не table, а (table*2), как например здесь viewtopic.php?f=20&t=5931&start=1600

1) Ну тогда в Вашем замечании нужно было сказать ещё, что писать надо не XL и XH, а ZL и ZH :-)
Так как для того доступа, который в принципе возможно осуществить через X, ни в одном из ассемблеров ничего делить не надо.

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

3) Да, спасибо за ссылку на обсуждение мной же приведённого кода :-)
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
john_rise
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн дек 17, 2007 13:15:43

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

Сообщение john_rise »

avreal, а можно поподробнее как адресоваться к байту а не к слову во flash?
Боишся - не делай. Делаешь - не бойся.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

У IAR и GCC в самих ассемблерах байтовая адресация.
И в ORG, и при использовании метки сам ассемблер пользуется байтовой адресацией.
Т.е.

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

   .org 200 ; начинаем с СОТОГО слова.
foo:   .byte 1
   .byte 2,3
moo:   .byte 3,4,5
Во флеше с сотого слова

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

   0201
   0303
   0504
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
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
john_rise
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн дек 17, 2007 13:15:43

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

Сообщение john_rise »

К сожалению не совсем понял. Насколько я знаю каждый последующий адрес памяти программ содержит по 2 байта (16 bit word). Значит шагать можно только по 2 байта, задав адрес имеем в доступе младший байт слова, для доступа к старшему адресу нужно сместиться:
lpm Z+

или:

adiw Z,0x01
lpm Z

Неужели я могу задать сразу адрес старшего байта слова? - и считать его без дополнительного действия-смещения?
Боишся - не делай. Делаешь - не бойся.
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

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

Сообщение ChipKiller »

john_rise писал(а):... Значит шагать можно только по 2 байта....
не путайте выполнение инструкций и адресацию к памяти программ - обратиться к любому байту ничто не мешает...
john_rise писал(а):Неужели я могу задать сразу адрес старшего байта слова...
.. это определяется содержимым младшего бита регистра ZL
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение 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 байта. Но сама подпрограмма вывода с доставанием адреса из стека и манипуляциями с ним длиннее, поэтому прибыль пойдет где-то с пятого-шестого вызова :-)
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение 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 из стека.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

avreal, вау! Надо запомнить эту магию! 8) Спасибо, сэнсэй!
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
SII
Вымогатель припоя
Сообщения: 635
Зарегистрирован: Пт янв 30, 2009 14:50:35
Откуда: Солнечногорск

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

Сообщение 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а стек есть, но сохранять в нём адрес возврата надо ручками.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение 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.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
SII
Вымогатель припоя
Сообщения: 635
Зарегистрирован: Пт янв 30, 2009 14:50:35
Откуда: Солнечногорск

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

Сообщение SII »

avreal писал(а):Вы читаете всё, или только то, на что можете хорошо ответить?


А Вы всё, хоть малость с Вашим мнением/описанием не согласующееся, считаете личным наездом?

И про то, что мнемоника ассемблера CALL была у PDP-11 -- как синоним к этой JSR PC


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

В любом случае и PDP-11-шный JSR, и ARM-овский BL гораздо удобнее для передачи константных параметров (не только строк), чем то, что приходится делать в AVR.


А вот в этом во мнениях сойдёмся :)
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

SII писал(а):
avreal писал(а):Вы читаете всё, или только то, на что можете хорошо ответить?

А Вы всё, хоть малость с Вашим мнением/описанием не согласующееся, считаете личным наездом?
Вполне возможно :-( Со стороны виднее.

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

Только вот начисто не могу припомнить, чтобы для применения CALL приходилось использовать какие-то файлы макроописаний, а разницы между наглухо встроенным макросом и мнемоникой не вижу. Не роясь в исходниках MACRO-11 их не отличить.
Ну забыл так забыл...
Хотя рановато :-(
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Steam
Грызет канифоль
Сообщения: 296
Зарегистрирован: Чт апр 19, 2007 15:27:28
Откуда: Мурманск, Россия
Контактная информация:

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

Сообщение 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? Слышал, что компилятор сам умеет создавать уникальные метки, но не нашёл как это делается.
Спасибо за внимание!
Гальваническое сопротивление - это восстание батареек
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

А я пробовал просто как обычно писать любую метку в макросе. После расстановки нескольких макросов прога нормально работала. Но это дело не так недавно было. :)
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
Steam
Грызет канифоль
Сообщения: 296
Зарегистрирован: Чт апр 19, 2007 15:27:28
Откуда: Мурманск, Россия
Контактная информация:

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

Сообщение Steam »

И правда работает! Боялся попробовать... Спасибо!
Гальваническое сопротивление - это восстание батареек
Аватара пользователя
Dako
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Сб июл 30, 2011 05:35:35

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

Сообщение 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 ;
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

Даже не знаю с чего начать...
В АВРСтудии прогоняли?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

Вы промахнулись строкой:
rjmp tccomp ;
она должна стоять на 7 месте, а не на 8.

А вообще, лучше использовать директивы .ORG
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение 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...?)
Ответить

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