2017-05-01 2 views
0

필자는 PIC18 주소 지정에 약간의 오류가 있습니다. 그래서 XC8에 의해 생성 된 lst 파일의 일부가 있습니다. 코드 끝에서 switch/case 연산자 비교 블록을 볼 수 있습니다. 그런 다음 case 부분으로 분기됩니다. 그래서 두 개의 일관된 레이블 l884와 l885를 얻을 수 있습니다. addreses는 1984h와 1990h (12 바이트 또는 6 단어의 거리)입니다. 우리가 그들로 분기되는 코드를 찾는 경우에, 우리는 볼 수 있습니다PIC18 이상한 주소 지정

E0F7의 BZ l885

E0EF의 BZ l884

을 거리는 8입니다! 6이 아니라 0C가 아니라 8! 이 함수는 switch()/case 블록을 계산 된 goto로 변경하려고합니다.이 점은 속도를 높이는 데 중요합니다. (이것이 내가이 목록을 보는 이유입니다.) 이제는 어떤 배율기를 사용해야할지 6, 8 또는 12? 같은 PIC18 어셈블러의

addr hex code  label disasm 
    001984    l884: 

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

          ;main.c: 407: Run(canIdCheckers[0].func); 
    001990 C100 F03C   movff _canIdCheckers,[email protected] 
    001994 C101 F03D   movff _canIdCheckers+1,[email protected]+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 

답변

0

일부 지침 : movff, call, goto 점프 계산에 있도록하는 것은이 지침에 대해 알아서, 더블 워드 및뿐만 아니라 하나의 단어입니다! 그리고 물론 승수는 없다. 단지 계산 명령이다.

라이트의 설명 : 라인

001984    l884:           << 
    001984 C102 F03C   movff _canIdCheckers+2,[email protected]  -2 
    001988 C103 F03D   movff _canIdCheckers+3,[email protected]+1 -2 
    00198C ECB2 F014   call _Run ;wreg free   -2 
    001990    l885:            << 
    001990 C100 F03C   movff _canIdCheckers,[email protected]  -2 -2 
    001994 C101 F03D   movff _canIdCheckers+1,[email protected]+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 어셈블리어 CODE : 라인 E0F7

계산 : bz l885 -9 = (256 -9) = 247 또는 은 0xEF의 ASM 코드 : E0EF

당신은 뛰어 PCLAT를 사용하는 습관 경우 그리고 나서 PCLATUPCLATH에 첫 번째 값을 넣고, 마지막으로 PCLATL으로 무엇을 업데이트하고 PCLAT 주소로 점프하면 주소를 저장하기 위해 테이블을 사용할 수 있습니다. 계산 된 점프를 사용하는 경우 모든 루틴이 nop 패딩으로 도달 할 수있는 것과 동일한 크기를 가져야합니다.

+0

나는 이것을 알고있다. 이 LST 파일에서 볼 수 있듯이 해당 부분의 세 명령 (설명 된 레이블 사이)은 모두 이러한 유형입니다. 모두 두 단어를 필요로합니다. 그러나 문제는 그것에 관한 것이 아니라 BZ 명령 인수 사이의 차이가 8 일 때, 주소 차이가 12 바이트 (6 단어) 였을 때의 이유는 무엇입니까? 그리고 곱셈에 대해서. 따라서 명령 블록 (전체적으로 48 일 것입니다) 크기는 3 명령 2 movff와 하나의 호출입니다. 따라서 마지막 블록을 실행하려면 PCLATH (U), PCL에 추가하기 전에 곱셈을 사용해야합니다. – EugenOS

+0

@EugenOS : 내 업데이트를 확인하십시오. –