Вставка ассемблерного кода в скетч

Тема в разделе "Arduino & Shields", создана пользователем avt34, 22 июн 2017.

  1. Igor68

    Igor68 Гуру

    Ясен пень AL и AH это половинки (младшая и старшая) регистра AX, который размером в 16 бит... но для 8-ми битных операций рассматриваются как два восьмеибитных регистра... это I8086(или его укороченного варианта I8088, который хоть и 16-битный, но шину данных имеет 8-битную).
    Думаю следует "перепилить" инструкции для AVR. Ранее реализовывал подсчёт CRC для весового терминала ТВ-009 от "ТЕНЗО-М"... был приведён в документации для x86 совместимой машины. У меня был ARM9(32 бита а флаг переноса использовался)... забил болт и реализовал на Си... точнее сэмулировал исходя из разрядности регистров x86... это не сложно... только описание системы команд надо для исходного процессора.
     
  2. mcureenab

    mcureenab Гуру

    rol и rcl пока не соображу. наверное оба rol (сдвиг через флаг переноса). в AVR rol двигает на 1 бит поэтому аргумент $1 не нужен.

    "mod1: rol %1\n\t"
    "rcl %0\n\t"
     
  3. mcureenab

    mcureenab Гуру

    jnc будет BRCC
    jnz будет BRNE
     
  4. avt34

    avt34 Нерд

    Спасибо, а то я тут в справочник уже зарылся.
     
  5. avt34

    avt34 Нерд

    Вот я тоже почти этим занят. Надо только сделать аппаратный имитатор этих весов.
     
  6. avt34

    avt34 Нерд

    На С пока переписывать не хочу, т.к. боюсь напартачить с подсчётом контрольной суммы и потом вообще концов не найти. Хотел точно "родной" код воспроизвести.
     
  7. mcureenab

    mcureenab Гуру

    все равно проверьте.

    x86 ROL

    [​IMG]



    AVR ROL Rd(0)<-C,Rd(n+1)<-Rd(n),C<-Rd(7). Т.е. это аналох x86 RCL (ниже картинка)

    x86 ROL это не VAR ROL, но нас тут интересует только CF.


    x86 RCL
    [​IMG]
     
  8. avt34

    avt34 Нерд

    т.е. получается что:
    x86 RCL = AVR ROL
    x86 ROL = ?
     
  9. mcureenab

    mcureenab Гуру

    Да. Но в данном случае x86 ROL = AVR ROL. Алгоритм прокручивает 8 раз по 1 биту, поэтому то что в него попало из CF не используется. Мы просто последовательно выталкиваем из него по 1 биту в CF и заталкиваем CF в регистр с суммой, а то что втекает в него с обратной стороны не важно.
     
  10. avt34

    avt34 Нерд

    ага.
    Пока получилось:
    Код (C++):
    byte CRCMaker(byte b_input,byte b_CRC)
    {
        asm volatile
        (
         "    ldi  r21,0x69"        "\n\t"
         "    mov  8,%r20"          "\n\t"
         "1:  rol  %1"              "\n\t"
         "    rol  %0"              "\n\t"
         "    brcc 2"               "\n\t"
         "    eor  %0,r21"          "\n\t"
         "2:  dec  %r20"            "\n\t"
         "    brne 1"               "\n\t"
         :"=r"(b_CRC)
         :"r"(b_input)
         );
        return b_CRC;
    }
    "operand number out of range"
     
  11. mcureenab

    mcureenab Гуру

    %r20 ????
     
  12. mcureenab

    mcureenab Гуру

    Зачем % ???
     
  13. avt34

    avt34 Нерд

    да, вот так правильно:

    Код (C++):
    byte CRCMaker(byte b_input,byte b_CRC)
    {
        asm volatile
        (
         "    ldi  r21,0x69"        "\n\t"
         "    mov  8,r20"           "\n\t"
         "1:  rol  %1"              "\n\t"
         "    rol  %0"              "\n\t"
         "    brcc 2"               "\n\t"
         "    eor  %0,r21"          "\n\t"
         "2:  dec  r20"             "\n\t"
         "    brne 1"               "\n\t"
         :"=r"(b_CRC)
         :"r"(b_input)
         :"r20","r21"
         );
        return b_CRC;
    }
     
  14. avt34

    avt34 Нерд

    Но всё равно:

    Код (C++):
    /tmp/ccEP8iww.s: Assembler messages:
    /tmp/ccEP8iww.s:992: Error: operand out of range: -213
    /tmp/ccEP8iww.s:995: Error: odd address operand: -431
    /tmp/ccEP8iww.s:995: Error: operand out of range: -217
     
  15. mcureenab

    mcureenab Гуру

    Mov на ldi заменить
     
  16. mcureenab

    mcureenab Гуру

    Ldi r20, 8

    Порядок операндов перепутан.

    Еще модет быть метки переходов надо словами обощвать а не числами.
     
  17. avt34

    avt34 Нерд

    Понял. Завтра тогда продолжу. Спасибо за помощь.
     
  18. avt34

    avt34 Нерд

    Проверил последние замечания. Вот так компилятор одобряет:
    Код (C++):
    byte CRCMaker(byte b_input,byte b_CRC)
    {
        asm volatile
        (
         "    ldi  r21,0x69"        "\n\t"
         "    ldi  r20,8"           "\n\t"
         "a:  rol  %1"              "\n\t"
         "    rol  %0"              "\n\t"
         "    brcc b"               "\n\t"
         "    eor  %0,r21"          "\n\t"
         "b:  dec  r20"             "\n\t"
         "    brne a"               "\n\t"
         :"=r"(b_CRC)
         :"r" (b_input)
         :"r20","r21"
         );
        return b_CRC;
    }
     
  19. mcureenab

    mcureenab Гуру

    Есть контрольный пример, проверить функцию?
     
  20. mcureenab

    mcureenab Гуру

    "=r" заменить на "+r"

    = Write-only operand, usually used for all output operands.
    + Read-write operand

    Instead of listing the same operand as both, input and output operand, it can also be declared as a read-write operand. This must be applied to an output operand, and the respective input operand list remains empty:

    Код (C++):
    asm volatile("mov __tmp_reg__, %A0" "\n\t"
    "mov %A0, %D0" "\n\t"
    "mov %D0, __tmp_reg__" "\n\t"
    "mov __tmp_reg__, %B0" "\n\t"
    "mov %B0, %C0" "\n\t"
    "mov %C0, __tmp_reg__" "\n\t"
    : "+r" (value));