Ассемблер avr. помогите с макросами

Тема в разделе "Микроконтроллеры AVR", создана пользователем Игорь_ьрогИ, 11 окт 2020.

  1. Всем здрасте). опыта мало, решил разобраться с макросами и вот)) не пойму в чем дело. AVR studio ругается на строку: .if @0<10. не пойму почему. вот что пишет:
    D:\main\project\AVRstudio_project\macros\macros.asm(9): error: syntax error, unexpected REGISTER.
    хотя в интернете много примеров написания с if/else. подскажите пожалуйста что делаю не так. Большое спасибо! Безымянный.png

    Код (C++):
    ;________________________________________________________________
    .device     attiny13A
    .nolist
    .include "C:\AVR_Studio\AvrAssembler2\Appnotes\tn13def.inc"
    .list
    ;________________________________________________________________
    ;-    макросы:
    .macro testMac
      .if  @0 < 10
           inc   @0
      .else
           clr   @0
      .endif
    .endm                    
    ;________________________________________________________________
    .cseg                           ;память программ
    ;_____ВЕКТОРЫ ПРЕРЫВАНИЙ:________________________________________            
    .org 0 rjmp  INIT               ;адрес 0 -первая выполняемая команда
    ;_____ИНИЦИАЛИЗАЦИЯ:_____________________________________________
    INIT:  ldi   r16,   ramend     ;установка стека на последний адрес ОЗУ
           out   SPL,   r16    
    ;_____ОСНОВНОЙ ЦИКЛ:_____________________________________________                              
    MAIN:  nop
           testMac r17
           nop
           rjmp  MAIN
     
  2. как написать макрос с принципом if/else?
     
  3. parovoZZ

    parovoZZ Гуру

    В названии темы добавь «ассемблер», чтобы знающие люди подтянулись. На «памагите» они, традиционно, не реагируют.
     
    Игорь_ьрогИ нравится это.
  4. Спасибо, добавил))
     
  5. a1000

    a1000 Гик

    А где вы нашли такие директивы?
    Код (C++):
    .if

    .else
     
  6. например тут. В интернете много примеров. уже и так пишу- #if #else #endif - ругаться программа перестала, но в else не переходит. если только не поставить в IF тупо 0
     

    Вложения:

  7. a1000

    a1000 Гик

    Я тоже в ASM не так давно, но такого не встречал ни разу. if---else это всё от лукавого Си, тут всё самому писать надо. Посоветую две книги. Краткий справочник по командам и учебный курс по AVR DI HALT. Во второй откройте раздел типовые конструкции - там всё расписано.
     

    Вложения:

  8. a1000

    a1000 Гик

    Вторая книга не лезет. Сейчас что-то придумаю.
     
  9. a1000

    a1000 Гик

  10. a1000

    a1000 Гик

    По мне макрос должен выглядеть так
    Код (C++):
        .MACRO testMac
             CPI @0,10   ;сравниваем @0 и 10  (фактически выполняется @0 - 10)
             BRCC METKA1 ;если @0>=10, не выскочит флаг С и мы перейдём на метку METKA1
                         ;в случае @0 < 10 выполняем следующий код
             inc   @0
             RJMP EXIT   ;уходим на конец макроса
             METKA1:     ;попадаем сюда если @0>=10
             clr   @0
             EXIT:
        .ENDMACRO                  
     
     
  11. ZAZ-965

    ZAZ-965 Гуру

    @Игорь_ьрогИ, по моему директивы препроцессора пишутся в начале строки без пробелов. Попробуйте
    Код (C++):
    .macro testMac
    .if  @0 < 10
           inc   @0
    .else
           clr   @0
    .endif
    .endm
     
  12. a1000

    a1000 Гик

    Поискал в интернете, действительно есть такие директивы. Но они немного не так работают как хочется Игорь_ьрогИ.
    Во первых - директива не компилируется и в код не вставляется. Это указания компилятору. Так, что процессор микроконтролера даже не знает, что они были в коде.
    Во вторых - разберёмся, что такое макрос. Мы заготавливаем определённый кусок кода и обзываем его макросом. Когда макрос вызывается, компилятор вставляет этот кусок кода в основную программу. Никаких переходов, как в случае с подпрограммами нет. И тут, в целях экономии програмной памяти, разработчики придумали хитрую штуку. Посмотрим пример на который ссылается ТС

    Код (C++):
    .MACRO XOUT
    .IF @0<64
    out      @0,@1
    .ELSE
    sts     @0,@1
    .ENDIF
    .ENDMACRO
    Кратко суть в следующем - оперативная память устроена так, что если адрес регистра до 64 запись производится командой OUT, если больше - STS. Человек решил автоматизировать, написал макрос XOUT. Что произойдёт при компиляции? Компилятор проверит адрес регистра приёмника. Если он меньше 64 то в основную программу будет подставлена строка out @0,@1. В противном случае - строка sts @0,@1. И на этом всё!!!!!! Никакие if---else в код тянуться не будут. Они умрут на стадии компиляции. А ТС хочет подсунуть компилятору переменную, по этому он справедливо ругается.
     
    Un_ka, Daniil, Igor68 и 2 другим нравится это.
  13. я понимаю, но вот вышеприведенный фрагмент кода у меня не работает!)) Судя по описанию (help avr studio) директивы пишутся после, через запятую. если убрать IF/ELSE то все переменные работают как надо.
     
  14. a1000

    a1000 Гик

    Мой вариант макроса из #10 запустили? Работает?
     
  15. в том что он работает у меня ни капли сомнений!
     
  16. Дело не в том как написать именно этот макрос. он сделан был как тест. что бы разобраться.
     
  17. a1000

    a1000 Гик

    Какой именно?