Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

Come artista, un uomo non ha altra patria in Europa che Parigi.

Friedrich Nietzsche 

Sondaggio:

Quale tra queste ? la pi? bella?

Monica Bellucci
Jennifer Lopez
Paola Barale
Selen
Sabrina Ferilli
Luisa Corna
Laura Freddi
Susanna Messaggio

visualizza risultati


 

Lavorare con le stringhe

Con il termine stringa non mi riferisco solo alla definizione classica di sequenza di caratteri, ma intendo una qualsiasi sequenza di byte, word,...

Le istruzioni che analizzeremo sono:

MOVS
SCAS
CMPS
LODS
STOS
INS
OUTS
REPxx

Queste instruzioni lavorano più o meno tutte nello stesso modo, secondo la seguente procedura:

  1. Assicuratevi che il Flag di Direzione sia a posto:

    se è 0 la stringa viene processata dal basso verso l'alto
    se è 1 la stringa viene processata dall'alto verso il basso
    (dove con alto e basso intendo le posizioni di memoria)

    Le istruzioni per azzerare e settare il DF sono CLD e STD rispettivamente.

  2. Caricate il numero di iterazioni nel registro CX.

  3. Caricate l'indirizzo iniziale della stringa sorgente in DS:SI e quello della stringa destinazione in ES:DI

  4. Usate le istruzioni di ripetizione al posto giusto (guardate la tabella seguente)

  5. Mettete l'istruzione appropriata come operando dell'istruzione di ripetizione

Vi riporto in una tabella le istruzioni con i prefissi che usano e su che tipo di operandi lavorano.

Istruzione Prefisso di rip. Sorg/Dest Registri
MOVS REP Entrambi DS:SI, ES:DI
SCAS REPE/REPNE Destinazione ES:DI
CMPS REPE/REPNE Entrambi ES:DI, DS:SI
LODS niente Sorgente DS:SI
STOS REP Destinazione ES:DI
INS REP Destinazione ES:DI
OUTS REP Sorgente DS:SI


Queste istruzioni hanno 2 tipi di sintassi:

[prefisso di ripetizione] istruzione [ES:[dest]],[sorgente]
[prefisso di ripetizione] istruzione < B|W|niente >

Dove B e W stanno per Byte e Word rispettivamente. Ad esempio con l'istruzione MOVS può essere data con operandi (byte o word), oppure posso usare MOVSB per spostare byte o MOVSW per spostare word.

I prefissi di ripetizione controllano il valore di CX e le eventuali condizioni specificate:

REP - Ripete fino a quando CX=0
REPE o REPZ - Ripete mentre è uguale o fino a quando CX=0
REPNE o REPNZ - Ripente mentre è diverso o fino a quando CX=0

Durante l'esecuzione un'istruzione preceduta da uno di questi prefissi segue il seguente algoritmo:

  1. Controlla il valore di CX, se CX=0 esce.
  2. Esegue l'operazione sulla stringa.
  3. Aumente il valore di SI e/o DI (o diminuisce, dipende dal DF). L'incremento è 1 per le operazioni sui byte, 2 per quelle sulle word.
  4. Decrementa CX
  5. Se l'istruzione è SCAS o CMPS controlla lo ZF (Zero Flag) ed esce se la condizione è falsa.
  6. Torna al punto 1.

Ora che abbiamo visto in generale come funzionano vediamo a cosa servono e come si usano una ad una.


MOVS

Questa serve per muovere una stringa da una locazione di memoria ad un altra.
La sintassi da usare è:

[REP] MOVS < destinazione >,< sorgente >
[REP] MOVSB
[REP] MOVSW

Dove i suffissi B e W stanno per Byte e Word.

Al solito ecco un esempio del loro utilizzo:

       .MODEL small
       .DATA
source DB 10 DUP ('0123456789')
destin DB 10 DUP (?)
       .CODE
       mov ax,@data     ;è un altro modo per carica il segmento
       mov ds,ax        ;lo metto in DS
       mov es,ax        ;e anche in ES
       ...
       ...
       ...
       cld
       mov cx,10               ;imposto il numero di iterazioni
       mov si,OFFSET source    ;Carico l'ind. del sorgente
       mov di,OFFSET destin    ;Carico l'ind. della desinazione
       rep movsb               ;sposto 10 byte

Spesso è piu efficiente spostare le stringhe come word che non come byte effettuando cosi metà iterazioni, (Attenzione però al numero di byte che compongono la scritta: deve essere pari).


SCAS

Questa istruzione è usata per cercare in una stringa uno specificato valore.

[REPE|REPNE] SCAS [ES:]< dest >
[REPE|REPNE] SCASB
[REPE|REPNE] SCASW

La stringa su cui operare deve essere all'indirizzo ES:DI e il valore da cercare deve essere in AL o in AX (byte o word rispettivamente). Quando trova il valore cercato viente settato lo ZF.

         .DATA
stringa  DB "Ken il guerriero"
lung     EQU $-stringa            ;lunghezza della stringa
pstringa DD string                ;puntatore alla stringa
         .CODE
         ...
         ...
         cld                      ;direzione dx-->sx
         mov cx,lung
         les di,pstringa
         mov al,'r'               ;carattere da cercare
         repne scasb              ;cerco
         jnz non_trovato          ;se non lo trovo salto
         ...              ;ES:DI punta al carattere che cercavo
         ...              ;in questo caso la prima r
         ...
         ...

non_trovato:


CMPS

Questa è usata per confrontare due stringhe.

[REPE|REPNE] CMPS < sorg >,[ES:]< dest >
[REPE|REPNE] CMPSB
[REPE|REPNE] CMPSW

NOTA: Attenzione che in CMPS il sorgente è l'operatore a sinistra !!!!

CMPS lavora confrontando uno ad uno i valori puntati da DI con quelli puntati da SI, se sono uguali viene settato lo ZF. Esempio:

        .MODEL Large
        .DATA
string1 DB "Ken il guerriero"
        .FARDATA        ;uso un altro segmento dati di tipo FAR
string2 DB "Ken il pippero"
lung    EQU $-string2
        .CODE
        mov ax,@data          ;carico i due segmenti in DS e ES
        mov ds,ax
        mov ax@fardata
        mov es,ax
        ...
        ...
        cld
        mov cx,lung
        mov si,OFFSET string1
        mov di,OFFSET string2
        repe cmpsb            ;confronto
        jz sono_uguali        ;se ZF=0 sono uguali
        dec di                ;altrimenti posiziono i puntatori
                              ;sul carattere diverso
        dec si
        ...
        ...
sono_uguali:


STOS

Questa serve per riempire una stringa con un determinato valore.
Sintassi:

[REP] STOS [ES:]< destinazione >
[REP] STOSB
[REP] STOSW

Il valore con cui riempire le stringhe va messo in AL o AX (byte o word risp.)
Esempio:

        .MODEL small
        .DATA
stringa DB 100 DUP(?)
        .CODE
        ...
        ...
        cld                       ;direzione dx-->sx
        mov ax,'aa'               ;valore con cui riempire
        mov cx,50                 ;numero di iterazioni
        mov di,OFFSET stringa     ;puntatore alla stringa
        rep stosw                 ;riempio con word

Notate che usando la STOSW che riempie con word, facendo 50 iterazioni riempio tutti i 100 byte !!!


LODS

Questa serve per caricare un valore da una stringa ad un registro.
La sintassi:

LODS [seg:]< sorgente >
LODSB
LODSW

Il valore che carichiamo va a finire in AL o AX e la stringa deve essere puntata da DS:SI. Al contrario delle altre istruzioni LODS non è usata con i prefissi, non avrebbe molto senso! Esempio:

        .DATA
numeri  DB 0,1,2,3,4,5,6,7,8,9
        .CODE
        ...
        ...
        cld
        mov cx,10                 ;numero di iterazioni
        mov si,OFFSET numeri
        mov ah,2
prendi: lodsb

        add al,'0'                ;converte in ASCII
        mov dl,al
        int 21h                   ;lo visualizza
        loop prendi               ;torna a cercare


OUTS, INS

Queste istruzioni servono per trasferire stringa dalle/alle porte.
La loro sintassi:

OUTS DX,[seg:]< sorgente >
OUTSB
OUTSW

INS [ES:]< destinazione >,DX
INSB
INSW

Il numero della porta va specificato in DX e non può essere specificato per valore.
Esempio:

        .DATA
count   EQU 100
buffer  DB count DUP(?)
inport  DW ?
        .CODE
        ...
        ...
        cld                          ;direzione
        mov cx,count                 ;numero iterazioni
        mov di,OFFSET buffer         ;puntatore al buffer
        mov dx,inport                ;numero della porta
        rep insb                     ;carica nel buffer

Si usa CX come contatore del numero di byte/word da trasferire.

 

Anche per stavolta avrei terminato, ho aggiunto al vostro bagaglio parecchie nuove istruzioni molto utili per copiare spostare ... dati, che è poi la cosa principale che un programma fa !!!

 

successivo
–«  INDICE  »–

 

 

 

 
Powered by paper&pencil (carta&matita ) - Copyright © 2001-2022 Cataldo Sasso