Tutorial Sezione Assembler

Dettaglio Istruzioni 

Le Schede del Tutorial

  Istruzioni della Cpu 80x86

SCHEDA n° 07 [I/ 026 di 198] 

    

    CMPS - Confronta i dati di 2 aree di memoria modificando le flags
     
bulletQuesta istruzione analizza il contenuto di 2 locazioni di memoria e modifica le flag in funzione del risultato.
bulletIn pratica simula la sottrazione del sorgente dalla destinazione senza però alterare il contenuto della destinazione (come farebbe invece l'effettiva sottrazione, SUB); questo basta per modificare le flag coinvolte dal risultato e a favorire gli eventuali salti condizionati (Jxx) conseguenti.
bulletPer funzionare correttamente è necessario specificare entrambi gli operandi, di solito con l'etichetta del primo dei dati di ciascuna area; in questo modo l'assemblatore è in grado di stabilire la dimensione del dato da assumere e collocare in memoria; se gli operandi non vengono dichiarati l'assemblatore segnala errore.
bulletSi tratta di una istruzione piuttosto efficiente, nata per confrontare il contenuto di 2 aree di memoria, per esempio 2 stringhe di caratteri.
bulletNonostante la necessità di dichiarare l'operando sorgente (solo per motivi di corretta compilazione) per default utilizza comunque le coppie di registri DS:SI per puntare in minuendo (destinazione) e ES:DI per puntare il sottraendo (sorgente), per cui l'uso di questa istruzione ha senso solo se, in precedenza, i registri SI e DI sono stati inizializzati con le etichette usate come operandi, per esempio anticipando la CMPS Depo01,ES:Depo02 con LEA SI,Depo01 e LEA DI,Depo02, vedi esempio successivo).
bulletIn questo è evidente una incongruenza con le convenzioni Intel, per cui il registro indice Sorgente per eccellenza è SI (Source Index) e quello Destinazione è DI (Destination Index): prendiamone atto senza farci intimorire....
bulletL'istruzione è particolarmente utile per confrontare 2 stringhe o tabelle; per trovare un determinato byte o carattere in una stringa o in una tabella è disponibile la SCAS che si basa sul medesimo principio di funzionamento.
bulletLe sue caratteristiche sono riassunte nella seguente tabella (leggi le istruzioni Legenda della Tabella):
         
CMPS Destinazione, Sorgente
CMP
S DS:[SI], ES:[DI]
 Cambia le Flag    simulando  { DS:[SI]  -  ES:[DI] }
 

Esempio di Applicazione

Cicli di Clock Mem
Acces

Bytes
Flag   influenzate
Mnemonico Operandi 86 268 386 486 O D I T S Z A P C

CMPS

 Byte  Ptr[SI],[DI]

22 8 10 8 2 1 #       # # # # #

CMPS

 Word Ptr[SI],[DI]

30 8 10 8 2 1 #       # # # # #
         
bulletLa tabella evidenzia la tipologia degli operandi: sono entrambi riferimenti a memoria e la cosa è decisamente inconsueta; ciò è dovuto al suo particolare modo di funzionare, che va al di là di un semplice confronto. Per questo sottolineiamo la sua capacità gestionale:
bulletIl dato prelevato dalle 2 locazioni di memoria ha la dimensione di un byte, di una word o di una doubleword (ma solo con 80386/486, nel qual caso i registri indice coinvolti sono ovviamente ESI e EDI).
bulletil segmento dell'area Sorgente (usata per puntare il sottraendo) è sempre ES.
bulletil segmento dell'area Destinazione (usata per puntare il minuendo) è per default, DS, ma può essere forzata a beneficio di un altro registro di segmento.
bulletdopo aver modificato le flag in funzione del confronto aggiorna il valore dei registri di offset (SI,DI o ESI,EDI), in funzione del valore della flag di direzione DF (che va quindi predisposta con certezza prima di iniziare il confronto):
bulletse DF=0 (direzione in avanti) ad entrambi i puntatori viene sommato 1 (cioè sono incrementati, se l'operando è un byte), 2 (se è una word) o 4 (se ha dimensione doubleword).
bulletse DF=1 (direzione indietro) ad entrambi i puntatori viene sottratto 1 (cioè sono decrementati, se l'operando è un byte), 2 (se è una word) o 4 (se ha dimensione doubleword).
bullet la presenza dei 2 puntatori operandi è richiesta dalla sintassi per consentire all'assemblatore di capire la dimensione dei dati da trattare; essi devono dunque essere dichiarati con la specifica della dimensione dei dati a cui fanno riferimento (Byte o Word o Dword Ptr).
bulletl'assemblatore compila comunque questa istruzione con lo stesso codice operativo con cui tratta le istruzioni da essa derivate, tutte prive di operando, cioè CMPSB, se i dati manipolati sono bytes, CMPSW se sono word, o CMPSD se doubleword.
bulletin tutti i casi non va dimenticato che le istruzioni di confronto stringhe usano per default i puntatori DS:SI e ES:DI, per cui è assolutamente necessario inizializzarli (insieme alla flag DF) prima di utilizzarle.
bulletQuesta potente istruzione esegue con un solo codice operativo il compito di ben 4 istruzioni (anche se a rigor di logica dovremmo mettere in conto anche il salvataggio e il recupero delle flag, dato che INC influisce su di loro), cioè equivale all'esecuzione del seguente codice:
         
MOV   AL,DS:[SI]
CMP   AL,ES:[DI]
PUSHF
INC   SI
INC   DI
POPF
     
bulletLa figura seguente mostra alcuni modi alternativi di scrivere questa istruzione:
          

Addr

Codifica Masm

Istruzione

0100
0132
0032 [.. 00..]
0032 [.. 00..]
Depo01 DB   50 DUP (00H)
Depo02 DB   50 DUP (00H)
---- ---------------- ------- ----------------------
0164
0165
0166
0167

0168
0169

016B
016C
016E
0170

0172
0174
0176

0178
017A
017C
A6
A6
A6
A7

A6
F3 A6

A6
2E A6
36 A6
26 A6

2E A6
36 A6
26 A6

2E A6
36 A6
26 A6








 
CMPS [Depo01],ES:[Depo02]
CMPS Byte Ptr [SI],[DI]
CMPS Byte Ptr DS:[SI],ES:[DI]
CMPS Word Ptr DS:[SI],Word Ptr ES:[DI]

CMPS Depo01,ES:Depo02
CMPS Depo01,ES:Depo02

CMPS DS:Depo01,ES:Depo02
CMPS CS:Depo01,ES:Depo02
CMPS SS:Depo01,ES:Depo02
CMPS ES:Depo01,ES:Depo02

CMPS CS:[SI],ES:Depo02
CMPS SS:[SI],ES:Depo02
CMPS ES:[SI],ES:Depo02

CMPS CS:[DI],ES:Depo02
CMPS SS:[DI],ES:Depo02
CMPS ES:[DI],ES:Depo02
         
bulletE' interessante osservare che, comunque sia scritta,  al netto dell'eventuale byte di override, viene sempre codificata con il byte A6  (se tratta bytes) o A7 (se tratta word).
bulletPrima di concludere è opportuno sottolineare che questa istruzione può fruire dell'operatore di autoripetizione REPE o REPNE: anteponendolo al suo mnemonico il processo di confronto viene ripetuto automaticamente CX volte su tutta l'area sotto test, a meno che non venga trovata una coppia di valori uguali (E) o diversi (NE); per il corretto uso dei questo prefisso è dunque necessario caricare preventivamente CX con il numero di confronti da eseguire.
bulletData l'utilità di questa tecnica viene proposto un esercizio d'esempio:
          

Addr

Codifica Masm

Istruzione

0100
0132

-----
0164
0165
0168
016C
0170
0172


0176
0177

0179
017A


017B
0032  [ ?? ]
0032  [ ?? ]
-----------
FC
B9 0032
8D 36 0100  
8D 3E 0132  
F3 A6
0F 85 0179  


90
EB 02

4E
4F


90
Depo01 
Depo02

----------------






;---------------
tutte_uguali:


;---------------
trovata_diversa:



continua:
      DB    50 DUP (?)
      DB    50 DUP (?)
-------------------------------
      CLD
      MOV   CX,50
      LEA   SI,Depo01
      LEA   DI,Depo02
REPE  CMPS Depo01,ES:Depo02
      JNE   trovata_diversa
;---------------------------
; servizio coppie uguali       
      NOP                      
      JMP  SHORT continua      
;------------------------------

      DEC   SI                 
      DEC   DI                 
; servizio prima coppia diversa
;------------------------------
 
      NOP
         
bulletL'analisi del codice suggerisce queste considerazioni:
bulletprendiamo nota della tecnica con cui viene riservata memoria per le 2 aree da confrontare, con la pseudoistruzione Dup.
bulletnotiamo la presenza dell'istruzione CLD, per imporre un'analisi in avanti.
bullet per inizializzare gli offset dei 2 puntatori si è fatto uso l'uso dell'istruzione LEA.
bulleti segment si ritengono quelli di default, DS e ES; notare la presenza dell'override ES: nella sintassi dell'istruzione di CMPS: se non si mette l'assemblatore s'arrabia, credendo sia DS anche per Depo02.
bulletil contatore CX è stato caricato con la dimensione di entrambe le aree e il prefisso REPE provvederà a ripetere automaticamente il confronto se i 2 dati assunti dalla coppia di locazioni sono uguali tra loro, fino all'esaurimento di tutti gli elementi.
bulletse le coppie sono tutte uguali il processo ha termine regolarmente e, essendo E la condizione d'uscita, l'istruzione JNE non verrà eseguita e il programma proseguirà subito sotto, nella zona di programma indicata dall'etichetta tutte_uguali.
bulletse viene rilevata una coppia diversa il processo verrà immediatamente interrotto prima della fine e, essendo ora NE la condizione d'uscita, l'istruzione JNE verrà eseguita e il programma proseguirà più in basso, nella zona di programma indicata dall'etichetta trovata_diversa.: le prime istruzioni da eseguire sono, in questo caso, il decremento dei puntatori DI e SI, così da favorire la localizzazione dei dati trovati diversi.

    

Pagina Precedente Scheda n° 07 Pagina Successiva Istruzioni Cpu 80x86 Torna al Menu delle Schede del "Tutorial" Lezioni - Vai al DownLoad dei files DOC Torna al Menu del "Tutorial"
Istruzione 026 - CMPS

    

SCHEDE » 1.Header EXE 2.PseudoOp MASM 3.Differenza tra Macro e Procedure
4.
Tabella Vettori 5.PSP 6.Stack 7.Istruzioni 80x86
8.La misura dell'Informazione 9.Numeri e Logica Binaria
TUTORIAL » Indirizzi Base | Registri Interni | Area Comunicaz. BIOS | Funzioni BIOS | Funzioni DOS
Prefazione | CAP 1 | CAP 2 | Schede | Palestra
Libreria ASM | Libreria MAC | Progetti ASM | Download | Info | Indice
Home 
Pascal|Manuali|Tabelle|Schede
Tutorial Assembly|Palestra Assembler
Aggiungi Giobe®2000 ai preferiti  
Motore
Ricerca
  Rendi Giobe®2000 pagina di Default
© 2001-2010  -  Studio Tecnico ing. Giorgio OBER
Tutti i diritti sono riservati