0

I have some missunderstanding in PIC18 addressing (as i see). So there is a part of lst file generated by XC8. At the end of code we can see the switch/case operator compare block, which then branches to case parts. So lets get two consistent labels l884 and l885. It's addreses is 1984h and 1990h (distance of 12 bytes or 6 words). But if we looks for the code, which is branches to them, we can see:

E0F7 bz l885

and

E0EF bz l884

the distance is 8 !!! not 6, not 0C, but 8 ???!!! i wish to change switch()/case block in this function to calculated goto, cause this point is critical to speed (this is the reason i watch this listing) but now i do not unserstand now which multiplier i must to use 6, 8, or 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
EugenOS
  • 31
  • 6

1 Answers1

0

Some instructions of PIC18 assembler, like: movff, call, goto are double word and not only single word, so at jump calculation take care about this instructions! And of course there is no multiplier, just instructions counting.

Added explanation:

  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

Calculation of line: bz l884 -17 = (256 - 17) = 238 or 0xF7 Asm CODE: E0F7

Calculation of line: bz l885 -9 = (256 -9) =247 or 0xEF Asm CODE: E0EF

If you wont to use PCLAT to jump then put first value to PCLATU and PCLATH, and at last to PCLATL what will update PC and jump to PCLAT address, you can use table to store addresses. If you use calcolated jump than all routines must have the same size what you can reach with nop pading.

GJ.
  • 10,810
  • 2
  • 45
  • 62
  • I know about this. As you can see from this LST file, all three commands in that part (between described labels) are these types. all takes two words. But, the question was not about that, but about WHY DIFFERENCE BETWEEN BZ COMMANDS ARGUMENTs was EIGHT, when the address difference was 12 bytes(6 words)? And about multiplication. thus the command block (which totally would be 48) size is 3 commands two movff and one call, so to run just some last blocks i must use multiplication before add to PCLATH(U),PCL. – EugenOS May 01 '17 at 21:03