PIC18 Какая-то странная адресация

У меня есть недоразумение в адресации PIC18 (как я вижу). Итак, есть часть lst файла, сгенерированного XC8. В конце кода мы видим блок сравнения оператора switch / case, который затем переходит к частям case. Итак, давайте получим две одинаковые метки l884 и l885. Его адреса - 1984h и 1990h (расстояние 12 байт или 6 слов). Но если мы поищем код, который является ответвлением к ним, мы увидим:

E0F7 bz l885

а также

E0EF bz l884

дистанция 8 !!! не 6, не 0С, а 8 ??? !!! Я хочу изменить блок switch () / case в этой функции на вычисляемый goto, потому что эта точка критична для скорости (это причина, по которой я смотрю этот листинг), но теперь я не понимаю, какой множитель я должен использовать 6, 8 , или 12?

  addr    hex  code     label  disasm
  001984                l884:

                           ;main.c: 405: Run(canIdCheckers[1].func);
  001984  C102  F03C            movff   _canIdCheckers+2,Run@addr
  001988  C103  F03D            movff   _canIdCheckers+3,Run@addr+1
  00198C  ECB2  F014            call    _Run    ;wreg free
  001990                l885:

                           ;main.c: 407: Run(canIdCheckers[0].func);
  001990  C100  F03C            movff   _canIdCheckers,Run@addr
  001994  C101  F03D            movff   _canIdCheckers+1,Run@addr+1
  001998  EFB2  F014            goto    _Run    ;wreg free
  00199C                l5504:
  00199C  501E                  movf    _canIdCheckerCount,w,c

                           ; Switch size 1, requested type "space"
                           ; Number of cases is 48, Range of values is 1 to 48
                           ; switch strategies available:
                           ; Name         Instructions Cycles
                           ; simple_byte          145    73 (average)
                           ;    Chosen strategy is simple_byte
  00199E  0A01                  xorlw   1   ; case 1
  0019A0  E0F7                  bz  l885
  0019A2  0A03                  xorlw   3   ; case 2
  0019A4  E0EF                  bz  l884

person EugenOS    schedule 01.05.2017    source источник


Ответы (1)


Некоторые инструкции ассемблера PIC18, например: movff, call, goto - это двойное слово, а не только одно слово, поэтому при вычислении переходов обратите внимание на эти инструкции! И, конечно, нет множителя, только счет инструкций.

Добавлено объяснение:

  001984                l884:                                         <<  
  001984  C102  F03C            movff   _canIdCheckers+2,Run@addr     -2
  001988  C103  F03D            movff   _canIdCheckers+3,Run@addr+1   -2
  00198C  ECB2  F014            call    _Run    ;wreg free            -2
  001990                l885:                                              <<
  001990  C100  F03C            movff   _canIdCheckers,Run@addr       -2   -2  
  001994  C101  F03D            movff   _canIdCheckers+1,Run@addr+1   -2   -2
  001998  EFB2  F014            goto    _Run    ;wreg free            -2   -2
  00199C                l5504:
  00199C  501E                  movf    _canIdCheckerCount,w,c        -1   -1
  00199E  0A01                  xorlw   1   ; case 1                  -1   -1
  0019A0  E0F7                  bz  l885                              -1 >>-1     
  0019A2  0A03                  xorlw   3   ; case 2                  -1 
  0019A4  E0EF                  bz  l884                            >>-1
                                                                    ========= 
                                                    (sum of words))  -17   -9

Расчет строки: bz l884 -17 = (256-17) = 238 или 0xF7 КОД Asm: E0F7

Расчет строки: bz l885 -9 = (256-9) = 247 или 0xEF КОД Asm: E0EF

Если вы не хотите использовать PCLAT для перехода, затем установите первое значение в PCLATU и PCLATH и, наконец, в PCLATL, который обновит компьютер и перейдет на PCLAT адрес, вы можете использовать таблицу для хранения адресов. Если вы используете вычисленный прыжок, тогда все подпрограммы должны иметь одинаковый размер, который вы можете достичь с помощью nop pading.

person GJ.    schedule 01.05.2017
comment
Я знаю об этом. Как видно из этого LST-файла, все три команды в этой части (между описанными метками) относятся к этим типам. все требует двух слов. Но вопрос был не в этом, а в том, ПОЧЕМУ РАЗНИЦА АРГУМЕНТОВ КОМАНД BZ была ВОСЕМЬ, когда разница адресов составляла 12 байтов (6 слов)? А по поводу умножения. таким образом, размер командного блока (всего 48) составляет 3 команды, два movff и один вызов, поэтому для запуска только некоторых последних блоков я должен использовать умножение перед добавлением к PCLATH (U), PCL. - person EugenOS; 02.05.2017