|   
 Gli opcodes
Una prima area di attenzione riguarda gli mnemonici delle nuove istruzioni
che hanno funzioni simili, ma più ampie di quelle dei mid-range. Ad esempio, gli shift possono essere effettuati con o senza carry, per cui la
lista : 
    
      
        | ;shift temporary left 2 times clrc
 rlf    TEMP0, f
 rlf    TEMP0, f
 |  potrà essere cambiata in :
 
    
      
        | ;shift temporary left 2 times rlncf   TEMP0, f
 rlcf    TEMP0, f
 |  Per chi proviene dall' avere già utilizzato i PIC mid-range, il passaggio ai
PIC 18F è, quindi, assai semplice, oltre che fonte di facilitazioni consistenti. Si possono però creare alcuni punti di ambiguità
per quanto riguarda il nuovo set di istruzioni Un primo punto è la
lunghezza delle istruzioni 18F che è, di base, 16 bits. Quindi le
istruzioni iniziano sempre in locazioni PARI e un salto ad un indirizzo
programma dispari è errato.Questo è importante per chi ha l' abitudine di utilizzare il simbolo $ per
puntare un salto.
 Più avanti un paragrafo tratta esplicitamente di questo argomento, anche
perchè la questione non è così semplice, esistendo nel set istruzioni anche a
32 bit, il che rende il calcolo "manuale" delle destinazioni
abbastanza complesso (basta usare label invece di indirizzi assoluti e il
problema è risolto ).
 
 Un altro punto riguarda le istruzioni di rotazione che, nei mid-range,
coinvolgono sempre il Carry (gli opcodes rlf  e rrf).
 Nei 18F, invece, sono disponibili due opcodes per ogni direzione della
rotazione, ovvero :
 
  rrcf /  rlcf 
    che agiscono come gli equivalenti  rlf / rrf e  rrncf /  rlncf che, invece, ruotano il registro oggetto
     SENZA coinvolgere
    il Carry Dunque una sostituzione diretta dei mid-range  rlf /
 rrf è, per gli enghanced, 
rlcf  /  rrcf ; in ogni caso MPASM, compilando per un PIC18, indica gli eventuali
opcodes  rlf /  rrf come errori. Inoltre varie delle nuove istruzioni hanno un diverso effetto sullo STATUS.Ad esempio le istruzioni di rotazione dei 18F possono modificare il bit Z
(oltre al nuovo flag N), cosa che, invece, nei mid range non era possibile.
Questo è abbastanza secondario, in quanto il programma mid-range non fa certo
uso di flag che non ha disponibili, mentre il fatto che un test successivo possa
fare leva sul flag Z (che l' istruzione PIC18 ha modificato) può rendere
difficoltoso il debug.
 Interessante l' istruzione di sottrazione ,  subwf dei mid-range,
che nei 18F ha come equivalente  subwfb (che, ricordiamo, hanno come
risultato di sottrarre W dal file f !).Esistono però una subwf, che non tiene conto del borrow , ma anche una
sunbfwb,
che opera in modo opposto, ovvero sottrae f da W,
tenendo conto del borrow.
 Per quanto riguarda i branch sui flag dello STATUS, ovvero bc,
bnc, bz,
bnz,
ecc., in effetti si tratta di branch e non di skip , ed  è un opcode  a
tutti gli effetti e non uno pseudo opcode o una macro : 
    
      
        | ;verify if zero addwf  res, f
 bc
 incf  res, f
 next ...
 |  da origine ad un immediato errore di assemblaggio perchè bc
si aspetta un indirizzo a cui effettuare il branch. Il sorgente dovrà
corretto con:
 
    
      
        | ;verify if zero addwf  res, f
 bc     next
 incf   res, f
 next ...
 |   Se poi è dichiarata una
macro con lo stesso nome bc, saranno segnalati altri errori. Analoga situazione nel caso in cui si siano usati gli pseudo opcodes
accettati da MPASM, pratica del tutto comune e lecita per i mid-range, ma non
più adeguata ai 18F. Ad esempio: 
    
      
        | skpnc addlw  0x01
 movwf   TEMP0
 |  non può essere sostituita da : 
    
      
        | bnc addlw  0x01
 movwf   TEMP0
 |  in quanto skpnc 
è uno "skip", che, se il carry è 0, salta la riga successiva  addlw  0x01
, mentre bnc 
è un "branch"  e richiede una label a cui saltare: 
    
      
        | bnc     next addlw   0x01
 next    movwf   TEMP0
 |  Questo punto è sensibile quando si voglia traslare un sorgente mid-range
dove sono stati utilizzati pseudo opcodes accettati da MPASM o macro del
genere: 
    
      
        | movf       TEMP1, w skpnz
 incfsz  TEMP1, w
 addwf     ACC1, f
 |  dove è stato usato lo pseudo opcodes (o la macro) skpnz
 , non più utilizzabile con i 18F, e che deve diventare:
 
    
      
        | movf       TEMP1, w bnz     $+4
 incfsz  TEMP1, w
 addwf     ACC1, f
 |  oppure: 
    
      
        | movf       TEMP1, w btfss   STATUS,Z
 incfsz  TEMP1, w
 addwf     ACC1, f
 |     
 La tabella seguente mette a confronto i vari metodi di branch e che
  evidenzia come l' uso delle istruzioni specifiche del set 18F permette
  una riduzione sia del codice che del tempo di esecuzione.:
 
    
    
      
        | branch
          del set PIC18 | metodi
          "tipo PIC16" |  
        | Metodo | Cicli | Metodo | Cicli | Metodo | Cicli |  
        | BC  carryset | 2 (1) / 1 | BTFSC  STATUS, C GOTO   carryset
 | 3 (2) / 2 | BTFSS STATUS, C GOTO  carry0
 | 2 (3) / 2 |  
        | BNC carry0 | BTFSS STATUS, C GOTO  carry0
 | BTFSC STATUS, C GOTO  carryset
 |  
        | BN  negative | BTFSC STATUS, N GOTO  negative
 | BTFSS STATUS, N GOTO  positive
 |  
        | BNN positive | BTFSS STATUS, N GOTO  positive
 | BTFSC STATUS, N GOTO  negative
 |  
        | BOV  ovflw | BTFSC STATUS, OV GOTO  ovflw
 | BTFSS STATUS, OV GOTO  novflw
 |  
        | BNOV novflw | BTFSS STATUS, OV GOTO  novflw
 | BTFSC STATUS, OV GOTO  ovflw
 |  
        | BZ    zero | BTFSC STATUS, Z GOTO  zero
 | BTFSS STATUS, Z GOTO  notzero
 |  
        | BNZ  notzero | BTFSS STATUS, Z GOTO  notzero
 | BTFSC STATUS, Z GOTO  zero
 |   
 
    
      
        |   NOTE: 
             branch del set 18F hanno la possibilità di spaziare -127
              / +128 istruzioni
per ampiezze maggiore è necessario ricorrere ai metodi
              "tipo PIC16" tenendo presente la possibilità di
              sostituire GOTO, che non ha limitazioni di distanza, con BRA
              per salti entro 1 k. |   
 
 Azione
    
      
        | La soluzione ideale è impadronirsi del nuovo set di opcodes e
comprenderne bene le funzioni. |    
    
 |