«

»

Opérations arithmétiques des PIC16

  • Détermination de la plage d’une valeur donnée comprise entre 0 et 255

Dans le second exemple on se propose de tester une valeur entre 0x20 et 0x27 incluses, puis entre 0x50 et 0x5F incluses et au delà afin d’exécuter un traitement particulier associé à chaque plage.

Une implémentation naturelle utilisant la valeur à tester et reprise avant chaque détermination de la plage peut être la suivante :

                     org 0x200
movf  0x7f, w        movf    R_SAVE_CMD,w      ; Restauration VAL a tester
sublw 0x1f           sublw   (0x20 – 1)        ; W = (0x20 – 1 – R_SAVE_CMD)
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x1F
goto  0x211          goto    range_00_1F       ; R_SAVE_CMD in [0x00..0x1F]
movf  0x7f, w        movf    R_SAVE_CMD,w      ; Restauration VAL a tester
sublw 0x27           sublw   0x27              ;  W = (0x27 – R_SAVE_CMD)
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x27
goto  0x212          goto    range_20_27       ; R_SAVE_CMD in [0x20..0x27]
movf  0x7f, w        movf    R_SAVE_CMD,w      ; Restauration VAL a tester
sublw 0x4f           sublw   (0x50 – 1)        ; W = (0x50 – 1 – R_SAVE_CMD)
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x4F
goto  0x213          goto    range_28_4F       ; R_SAVE_CMD in [0x28..0x4F]
movf  0x7f, w        movf    R_SAVE_CMD,w      ; Restauration VAL a tester
sublw 0x7f           sublw   0x7F              ; W = (0x7F – R_SAVE_CMD)
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x7F
goto  0x214          goto    range_50_7F       ; R_SAVE_CMD in [0x50..0x7F]
goto  0x215          goto    range_80_FF       ; R_SAVE_CMD in [0x80..0xFF]

Notice

Cette implémentation coute une instruction supplémentaire (movf R_SAVE_CMD,w) par plage à tester. Dans l’implémentation suivante, cette instruction est gagnée (sauf pour la 1ère plage) en utilisant le même principe qui consiste à retrouver la valeur à tester  en  faisant une simple opération arithmétique module 256.

                     org 0x200
movf 0x7f, w         movf    R_SAVE_CMD,w      ; Restauration VAL a tester
sublw 0x1f           sublw   (0x20 – 1)        ; W = (0x20 – 1 – R_SAVE_CMD)
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x1F
goto 0x211           goto    range_00_1F       ; R_SAVE_CMD in [0x00..0x1F]
addlw 0x8            addlw   (0x27 – (0x20 – 1))
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x27
goto 0x212           goto    range_20_27       ; R_SAVE_CMD in [0x20..0x27]
addlw 0x28           addlw   (0x50 – 10x27)
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x4F
goto 0x213           goto    range_28_4F       ; R_SAVE_CMD in [0x28..0x4F]
addlw 0x30           addlw   (0x7F – (0x50 – 1))
btfsc 0x3, 0         skpnc                     ; Test autour du pivot 0x7F
goto 0x214           goto    range_50_7F       ; R_SAVE_CMD in [0x50..0x7F]
goto 0x215           goto    range_80_FF       ; R_SAVE_CMD in [0x80..0xFF]

Important!

On notera qu’à l’occasion de la dernière implémentation que le comportement des 2 instructions add et sub vis à vis du drapeau Carry est strictement identique. Cette propriété permet ainsi de réaliser les simplifications apportées pour l’optimisation du code.