L’Assembler 8086
Istruzioni per la Manipolazione delle Stringhe
M. Rebaudengo - M. Sonza Reorda
Politecnico di Torino
Dip. di Automatica e Informatica
1
M. Rebaudengo, M. Sonza Reorda
Istruzioni per la manipolazione
delle stringhe
L’8086 possiede un gruppo di istruzioni per la
manipolazione di stringhe, ossia di sequenze contigue di byte
o word.
Le operazioni che possono essere effettuate sono:
• la copiatura da una stringa sorgente ad una stringa
destinazione;
• il confronto tra due stringhe;
• la ricerca di un valore all’interno di una stringa;
• la modifica del contenuto di una stringa.
2
M. Rebaudengo, M. Sonza Reorda
Istruzioni per la manipolazione
di stringhe
(segue)
Tutte le istruzioni per la manipolazione delle stringhe hanno alcune
caratteristiche comuni:
• possono lavorare su una o due stringhe;
• i due registri utilizzati come indici all’interno delle due stringhe
vengono automaticamente aggiornati al termine dell’operazione
elementare, in modo da puntare ciascuno all’elemento successivo
all’interno della rispettiva stringa;
• ciascuna delle istruzioni di manipolazione esegue una singola
operazione: l’assembler 8086 fornisce un meccanismo per la
ripetizione di tali operazioni per un numero prefissato di volte o fino
al verificarsi di una determinata condizione.
3
M. Rebaudengo, M. Sonza Reorda
Preparazione dei registri
Tutte le istruzioni per la manipolazione delle stringhe
richiedono che:
• la stringa sorgente si trovi nel segmento di dato
puntato da DS; il registro SI memorizza l’indirizzo
di offset dell’elemento da processare all’interno della
sequenza.
• l’eventuale stringa destinazione si trovi nel segmento
extra di dato puntato da ES; il registro DI memorizza
l’indirizzo di offset dell’elemento da processare.
4
M. Rebaudengo, M. Sonza Reorda
Extra e data segment coincidenti
Se i dati sono contenuti in un unico segmento di dato, le operazioni da
fare per predisporre i registri per la manipolazione di stringhe sono le
seguenti:
• copiare il contenuto del registro DS nel registro ES in modo da far
coincidere i due segmenti;
• copiare gli offset delle due stringhe nei registri SI e DI.
Esempio
LUNG
STR1
STR2
5
EQU 100
.DATA
DB
LUNG DUP (?)
DB
LUNG DUP (?)
.CODE
...
PUSH DS
POP
ES
LEA SI, STR1
LEA DI, STR2
M. Rebaudengo, M. Sonza Reorda
Extra e data segment separati
La condizione di default prevista è quella di avere la stringa sorgente
nel segmento di dato e la stringa destinazione nel segmento dati extra.
In questo caso per caricare i registri SI e DI basta eseguire l’istruzione
di LEA.
6
.MODEL COMPACT ; 1 segm. di codice, più segm. di dato
.FARDATA
DSEG
STR1 DB 100 DUP (?)
.FARDATA
ESEG
STR2 DB 100 DUP (?)
.CODE
...
ASSUME DS:DSEG, ES:ESEG
MOV AX, DSEG
MOV DS, AX
MOV AX, ESEG
MOV ES, AX
LEA SI, STR1
LEA DI, STR2
M. Rebaudengo, M. Sonza Reorda
Stringa destinazione
nel segmento di dato
Nel caso in cui la stringa destinazione si trovi nel segmento di dato
ed il segmento extra sia usato per memorizzare un diverso
segmento di dati, occorre far coincidere temporaneamente il
contenuto dei registri DS ed ES.
Le operazioni da eseguire sono le seguenti:
• salvare il contenuto di ES
• copiare il contenuto di DS in ES
• eseguire l’istruzione di manipolazione di stringhe
• ripristinare il contenuto del registro ES.
7
M. Rebaudengo, M. Sonza Reorda
Esempio
LUNG
STR1 DB
STR2 DB
STRADD
8
.MODEL COMPACT
EQU 100
.FARDATA ESEG
LUNG DUP (?)
LUNG DUP (?)
DD
STR2
...
.CODE
...
PUSH ES
; salvataggio di ES
LEA SI, STR1 ; caricamento di SI
LES DI, STRADD; caricamento di DI e ES
...
; istruzioni di manipolazione
POP ES
; ripristino di ES
M. Rebaudengo, M. Sonza Reorda
La ripetizione delle istruzioni
per la manipolazione di stringhe
Ogni istruzione per la manipolazione di stringhe opera su
un singolo elemento della stringa (byte o word) per volta.
Per processare l’intera stringa occorre eseguire un ciclo che
permetta di ripetere l’istruzione di manipolazione per tutti
gli elementi della stringa.
9
M. Rebaudengo, M. Sonza Reorda
La ripetizione delle istruzioni
per la manipolazione di stringhe
(segue)
Il processore mette a disposizione una classe di istruzioni utili per
implementare i cicli per la manipolazione delle stringhe:
• REP
• REPE
• REPNE.
Queste istruzioni vengono utilizzate in abbinamento con una delle
istruzioni di manipolazione ed appaiono sulla stessa riga del codice.
10
M. Rebaudengo, M. Sonza Reorda
La ripetizione delle istruzioni
per la manipolazione di stringhe
(segue)
Formato
REPxxx
string_istr
Funzionamento
Questo
statement
ripete
l’esecuzione
dell’istruzione
string_istr per un numero di volte pari al contenuto del
registro CX.
11
M. Rebaudengo, M. Sonza Reorda
La ripetizione delle istruzioni
per la manipolazione di stringhe
(segue)
Le istruzioni REPE e REPNE sono due varianti che possono
essere utilizzate abbinate alle istruzioni di confronto e di
ricerca.
• L’istruzione REPE ripete il ciclo finché il registro CX
ha un valore diverso da 0 e le parole confrontate sono
uguali.
• L’istruzione REPNE ripete il ciclo finchè il registro CX
ha un valore diverso da 0 e le parole confrontate sono
diverse.
12
M. Rebaudengo, M. Sonza Reorda
La ripetizione delle istruzioni
per la manipolazione di stringhe
(segue)
Per utilizzare le istruzioni REP, REPE e REPNE occorre
dunque caricare il registro CX con la dimensione della
stringa.
Analogamente a quanto avviene nel caso dell’istruzione
LOOP, ad ogni esecuzione dell’istruzione il contenuto del
registro CX viene decrementato di una unità.
La differenza sostanziale tra l’istruzione LOOP e
l’istruzione REP è che l’istruzione REP permette la
ripetizione di un’unica istruzione di manipolazione di
stringhe, mentre la LOOP permette di ripetere una
generica sequenza di istruzioni.
13
M. Rebaudengo, M. Sonza Reorda
Esempio
LUNG
STR1
STR2
14
EQU 100
.DATA
DB
LUNG DUP (?); stringa sorgente
DB
LUNG DUP (?); stringa destinaz.
...
.CODE
...
PUSH DS
POP ES
LEA SI, STR1
LEA DI, STR2
MOV CX, LUNG
REP MOVSB
...
M. Rebaudengo, M. Sonza Reorda
Esempio (II)
LUNG
STR1
STR2
ciclo:
15
EQU 100
.DATA
DB
LUNG DUP (?)
DB
LUNG DUP (?)
...
.CODE
...
PUSH DS
POP ES
LEA SI, STR1
LEA DI, STR2
MOV CX, LUNG
MOVSB
LOOP ciclo
...
Equivalente al
precedente
M. Rebaudengo, M. Sonza Reorda
Aggiornamento del contenuto dei
registri indice
Le istruzioni per la manipolazione delle stringhe prevedono
che i registri SI e DI contengano l’offset delle parole da
processare.
Quando si esegue ripetutamente una stessa istruzione di
manipolazione, il contenuto dei registri è automaticamente
aggiornato per indirizzare la parola successiva nella
stringa.
16
M. Rebaudengo, M. Sonza Reorda
Aggiornamento del contenuto dei
registri indice
(segue)
Il contenuto dei registri SI e DI è aggiornato automaticamente dalla
stessa istruzione di manipolazione, in base al valore del flag di
direzione (DF):
• se il flag DF vale 0, dopo ogni esecuzione dell’istruzione di
manipolazione il contenuto dei registri di indice è incrementato
di una unità per le stringhe di byte e di due unità per le stringhe
di word.
• se il flag DF vale 1, dopo ogni esecuzione dell’istruzione di
manipolazione il contenuto dei registri di indice è decrementato
di una unità per le stringhe di byte e di due unità per le stringhe
di word.
17
M. Rebaudengo, M. Sonza Reorda
Aggiornamento del contenuto dei
registri indice
(segue)
A seconda del valore del flag DF le operazioni sulle stringhe vengono
quindi eseguite in avanti con DF = 0 (forward) oppure all’indietro
con DF = 1 (backword).
Il valore del flag DF è modificato mediante le due istruzioni STD e CLD.
L’istruzione STD forza il flag DF ad 1, mentre l’istruzione CLD forza il
flag DF a 0.
È bene ricordarsi di aggiornare sempre il valore del flag DF prima di
eseguire un ciclo di manipolazione di stringhe, in quanto il processore
non garantisce di mantenere costante il valore di DF tra due cicli di
manipolazione.
18
M. Rebaudengo, M. Sonza Reorda
Scansione in avanti
LUNG
STR1
STR2
19
EQU 100
.DATA
DB
LUNG DUP (?)
DB
LUNG DUP (?)
...
.CODE
PUSH DS
POP ES
LEA SI, STR1
LEA DI, STR2
MOV CX, LUNG
CLD
REP MOVSB
...
; flag DF = 0
M. Rebaudengo, M. Sonza Reorda
Scansione all’indietro
LUNG
STR1
STR2
20
EQU 100
.DATA
DB
LUNG DUP
DB
LUNG DUP
...
.CODE
PUSH DS
POP ES
LEA SI, STR1
LEA DI, STR2
MOV CX, LUNG
STD
REP MOVSB
...
(?)
(?)
+ SIZE STR1 - TYPE STR1
+ SIZE STR2 - TYPE STR2
; flag DF = 1
M. Rebaudengo, M. Sonza Reorda
Riepilogo delle operazioni
necessarie per la manipolazione
delle stringhe
• Preparazione dei registri
• caricamento del registro CX con il numero di elementi
della stringa
• aggiornamento del flag DF
• esecuzione dell’istruzione REP (o REPE o REPNE),
abbinata all’opportuna istruzione di manipolazione.
21
M. Rebaudengo, M. Sonza Reorda
Istruzioni per la Manipolazione
delle Stringhe e Interrupt
Al termine di ogni istruzione primitiva i registri indice ed
eventualmente CX (se vi è un prefisso) sono aggiornati; nel
caso esista un prefisso, IP non viene aggiornato se non al
termine dell'iterazione.
In questo modo il processore può rilevare e servire richieste
di interrupt senza attendere il termine dell'istruzione, che
può essere ripresa dal punto in cui era stata interrotta.
22
M. Rebaudengo, M. Sonza Reorda
Copiatura di una stringa
Le istruzioni MOVSB e MOVSW permettono di copiare una
stringa da un indirizzo sorgente ad un indirizzo
destinazione.
Formato
MOVSB
MOVSW
Funzionamento
L’istruzione MOVSB copia il byte avente indirizzo DS:SI
nella locazione di memoria ES:DI. L’istruzione MOVSW
copia la word avente indirizzo DS:SI nella locazione di
memoria ES:DI.
Al termine dell’esecuzione dell’istruzione vengono
aggiornati entrambi i registri di indice.
23
M. Rebaudengo, M. Sonza Reorda
Esempio: scalamento
di una stringa di 5 posizioni
LUNG
STR
24
EQU 100
.DATA
DB
LUNG DUP (?)
DB
5 DUP (?)
...
.CODE
PUSH DS
POP ES
LEA SI, STR
LEA DI, STR + 5
MOV CX, LUNG
CLD
; scansione in avanti
REP MOVSB
...
M. Rebaudengo, M. Sonza Reorda
Esempio: scalamento
di
una
stringa
di
5
posizioni
LUNG
EQU 100
STR
25
.DATA
DB
LUNG DUP (?)
DB
5 DUP (?)
...
.CODE
...
PUSH DS
POP ES
LEA SI, STR + SIZE STR - TYPE STR
LEA DI, STR + SIZE STR - TYPE STR + 5
MOV CX, LUNG
STD
; scansione all’indietro
REP MOVSB
...
M. Rebaudengo, M. Sonza Reorda
Inizializzazione di una stringa
Si vuole realizzare un frammento di programma che esegua
l’inizializzazione di una stringa replicando più volte una
stessa sequenza di caratteri.
main()
{
char vett[101], i;
...
vett[0]='\0';
for (i=0; i<20; i++)
strcat(vett,"Ciao ");
...
}
26
M. Rebaudengo, M. Sonza Reorda
LUNG
STRING
27
Soluzione
Assembler
EQU 95
.MODEL
small
.STACK
.DATA
DB
"Ciao ", LUNG DUP(?)
.CODE
...
PUSH DS
POP ES
LEA SI, STRING
LEA DI, STRING + 5
MOV CX, LUNG
CLD
REP MOVSB
...
M. Rebaudengo, M. Sonza Reorda
Confronto tra stringhe
Le istruzioni CMPSB e CMPSW permettono di confrontare due stringhe
tra loro.
Formato
CMPSB
CMPSW
Funzionamento
L’istruzione CMPSB lavora con stringhe di byte, mentre l’istruzione
CMPSW lavora con stringhe di word.
Ad ogni esecuzione dell’istruzione CMPSB/CMPSW viene effettuato il
confronto tra la locazione di memoria avente indirizzo DS:SI e la
locazione di memoria avente indirizzo ES:DI.
Al termine dell’esecuzione dell’istruzione vengono aggiornati entrambi
i registri di indice.
28
M. Rebaudengo, M. Sonza Reorda
Confronto tra stringhe
L’istruzione di confronto viene tipicamente usata
congiuntamente alle istruzioni REPE e REPNE, ed in
particolare:
• si usa REPE se si vuole verificare se due stringhe sono
uguali;
• si usa REPNE se si vuole verificare se due stringhe sono
diverse.
Il ciclo di confronto termina al verificarsi di una delle
seguenti condizioni:
• la stringa è terminata (il registro CX ha valore nullo)
• è stata trovata una disuguaglianza (con REPE) od una
uguaglianza (con REPNE).
29
M. Rebaudengo, M. Sonza Reorda
Esempio
LUNG
STR1
STR2
30
EQU 100
.DATA
DB
LUNG DUP (?)
DB
LUNG DUP (?)
...
.CODE
...
PUSH DS
POP ES
LEA SI, STR1
LEA DI, STR2
MOV CX, LUNG
CLD
REPE CMPSB
...
M. Rebaudengo, M. Sonza Reorda
Confronto tra stringhe
(segue)
Ogni esecuzione dell’istruzione di confronto aggiorna i flag.
È possibile analizzare lo stato del flag ZF per verificare se la
condizione di uguaglianza è stata verificata oppure no.
Questa operazione può essere eseguita mediante un’istruzione di
salto condizionato.
All’uscita del ciclo è normalmente utile conoscere quale parola ha
causato la terminazione. Tale informazione è contenuta nel registro
SI.
Poiché il registro SI è aggiornato alla fine di ciascun confronto,
all’uscita del ciclo il registro SI contiene l’offset della parola
successiva a quella che ha causato la terminazione.
31
M. Rebaudengo, M. Sonza Reorda
LUNG
STR1
STR2
lab1:
lab2:
32
Esempio
EQU
100
.DATA
DB
LUNG DUP (?)
DB
LUNG DUP (?)
.CODE
Confronta due stringhe
e scrive in AL:
…
• 0, se sono uguali
PUSH DS
POP ES
• il primo carattere
diverso, se non lo
LEA
SI, STR1
sono.
LEA
DI, STR2
MOV
CX, LUNG
CLD
REPE CMPSB
JE
lab1
; stringhe uguali ?
DEC
SI
; No: decrementa SI
MOV
AL, [SI]
; primo carattere diverso
JMP
lab2
MOV
AL, 0
…
M. Rebaudengo, M. Sonza Reorda
Scansione di una stringa
Le istruzioni SCASB e SCASW permettono di scandire una stringa
per ricercare un valore specifico.
Formato
SCASB
SCASW
Funzionamento
L’istruzione SCASB lavora con stringhe di byte, mentre l’istruzione
SCASW lavora con stringhe di word.
L’istruzione SCASB usa i registri AL e DI, mentre l’istruzione
SCASW usa i registri AX e DI.
I registri AL e AX contengono il valore da confrontare, mentre DI
contiene l’offset della stringa da scandire.
Al termine dell’esecuzione dell’istruzione viene aggiornato il
contenuto del registro DI.
33
M. Rebaudengo, M. Sonza Reorda
Scansione di una stringa
(segue)
Ad ogni esecuzione dell’istruzione SCASB/SCASW viene
effettuato il confronto tra il contenuto della locazione ES:DI ed
il contenuto del registro accumulatore.
Anche le istruzioni SCASB e SCASW utilizzano le istruzioni
REPE e REPNE per generare il ciclo.
• per cercare un valore diverso dal contenuto dei registri AL
ed AX si usa l’istruzione REPE,
• per cercare un valore coincidente al contenuto dei registri
AL ed AX si usa l’istruzione REPNE.
34
M. Rebaudengo, M. Sonza Reorda
Scansione di una stringa
(segue)
Il ciclo di scansione termina al verificarsi di una delle
seguenti condizioni:
• la stringa è terminata (il registro CX ha valore nullo).
• è stata trovata una disuguaglianza tra il contenuto del
registro accumulatore e la stringa indirizzata da DI
(con REPE), oppure è stata trovata una uguaglianza
tra il contenuto del registro accumulatore e la stringa
indirizzata da DI (con REPNE).
35
M. Rebaudengo, M. Sonza Reorda
Esempio
Si realizzi un frammento di programma che scandisca una stringa di
caratteri e che visualizzi il primo carattere diverso dal carattere spazio.
#include <stdio.h>
main()
{
int i;
char string[25];
strcpy(string," Fatti non foste a viver come bruti ...");
for (i=0 ; i<25 ; i++)
if (string[i] != ' ')
{
printf("%c",string[i]);
break;
}
...
}
36
M. Rebaudengo, M. Sonza Reorda
Soluzione
Assembler
.MODEL
small
STRING
LUNG
ST_ADD
37
esci:...
.STACK
.DATA
DB
" Fatti non foste a viver come bruti"
EQU
$-STRING
DD
STRING
...
.CODE
...
MOV
AL, " "
LES
DI, ST_ADD
MOV
CX, LUNG
CLD
REPE SCASB
JE
esci
DEC
DI
MOV
DL, [DI]
MOV
AH, 02H
; visualizza
INT
21H
M. Rebaudengo, M. Sonza Reorda
Inizializzazione di una stringa
Le istruzioni STOSB e STOSW permettono di inizializzare tutti gli
elementi di una stringa ad un determinato valore.
Formato
STOSB
STOSW
Funzionamento
L’istruzione STOSB lavora con stringhe di byte, mentre l’istruzione
STOSW lavora con stringhe di word.
L’istruzione STOSB usa i registri AL e DI, l’istruzione STOSW usa i
registri AX e DI.
I registri AL e AX contengono il valore con cui viene inizializzata la
stringa, DI contiene l’offset della stringa da inizializzare.
38
M. Rebaudengo, M. Sonza Reorda
Inizializzazione di una stringa
(segue)
Al termine dell’esecuzione dell’istruzione viene aggiornato
il contenuto del registro DI.
L’effetto delle istruzioni STOSB/STOSW è di copiare il
valore contenuto nei registri AL (od AX) nella locazione di
memoria avente indirizzo ES:DI.
39
M. Rebaudengo, M. Sonza Reorda
Esempio
Si vuole realizzare un frammento di programma che scriva
il carattere spazio in tutti gli elementi di una stringa.
main()
{
int i;
char str[26];
...
for (i=0 ; i<25 ; i++)
str[i] = ' ';
str[25] = '\0';
...
}
40
M. Rebaudengo, M. Sonza Reorda
Soluzione Assembler
LUNG
STR
ST_ADD
41
EQU 25
.MODEL small
.STACK
.DATA
DB
LUNG DUP(?)
DD
STR
...
.CODE
...
MOV AL, " "
LES DI, ST_ADD
MOV CX, LUNG
CLD
REP STOSB
...
M. Rebaudengo, M. Sonza Reorda
Elaborazione di una stringa
Le istruzioni LODSB e LODSW permettono di copiare un
elemento di una stringa nei registri accumulatore.
Formato
LODSB
LODSW
Funzionamento
L’istruzione LODSB lavora con stringhe di byte, mentre
l’istruzione LODSW lavora con stringhe di word.
L’istruzione LODSB usa i registri AL e SI, l’istruzione
LODSW usa i registri AX e SI.
42
M. Rebaudengo, M. Sonza Reorda
Elaborazione di una stringa
(segue)
L’effetto delle istruzioni LODSB e LODSW è quello di copiare
il contenuto della locazione di memoria avente indirizzo
DS:SI nei registri AL o AX.
43
M. Rebaudengo, M. Sonza Reorda
Esercizio
Conteggio del numero di spazi bianchi in una stringa di
caratteri.
main()
{
char sorg[100];
int i, count = 0;
...
for (i=0 ; i<100 ; i++)
if (sorg[i] == ' ')
count++;
...
}
44
M. Rebaudengo, M. Sonza Reorda
LUNG
EQU 100
.MODEL
small
.STACK
.DATA
SORG DB
LUNG DUP (?)
...
.CODE
...
LEA SI, SORG
MOV CX, LUNG
MOV BX, 0
CLD
ciclo: LODSB
CMP AL, ' '
; AL = ' ' ?
JNE next
; No: va a next
INC BX
next: LOOP ciclo
Soluzione Assembler
45
...
; Sì: fine
M. Rebaudengo, M. Sonza Reorda
Elaborazione di una stringa
(segue)
Le istruzioni LODSB e LODSW sono utili in coppia con le istruzioni
STOSB/STOSW per elaborare il contenuto di una stringa, ossia per eseguire
la stessa operazione su tutte le parole di una stringa.
Per elaborare una stringa:
• si copia l’offset della stringa sorgente in SI;
• si copia l’offset della stringa destinazione in DI;
• si copia la lunghezza della stringa in CX;
• si aggiorna il flag DF;
• per ogni parola della stringa sorgente:
• si copia la parola nel registro accumulatore
• si elabora il contenuto del registro
• si copia il contenuto accumulatore nella stringa destinazione.
46
M. Rebaudengo, M. Sonza Reorda
Esempio
47
Si vuole realizzare un frammento di programma che trasferisca un
vettore di interi da una zona di memoria ad un’altra, con la
condizione che i termini negativi siano trasformati in termini di
valore nullo.
main()
{
int sorg[100], dest[100], i;
...
for (i=0 ; i<100 ; i++)
if (sorg[i] < 0)
dest[i] = 0;
else
dest[i] = sorg[i];
...
}
M. Rebaudengo, M. Sonza Reorda
Soluzione Assembler
LUNG EQU 100
.MODEL
small
.STACK
.DATA
SORG
DW
LUNG DUP (?)
DEST
DW
LUNG DUP (?)
ST_ADD
DD
DEST
...
.CODE
...
LEA SI, SORG
LES DI, ST_ADD
48
M. Rebaudengo, M. Sonza Reorda
MOV
CLD
ciclo: LODSW
CMP
JNL
MOV
lab:
STOSW
LOOP
...
49
CX, LUNG
AX, 0
lab
AX, 0
ciclo
M. Rebaudengo, M. Sonza Reorda
Esercizio
Si vuole realizzare un frammento di programma che trasferisca una
stringa di caratteri da un’area di memoria sorgente ad un’area di
memoria destinazione, eseguendo la conversione da caratteri minuscoli
a caratteri maiuscoli.
main()
{
char sorg[100], dest[100];
int i;
...
for (i=0 ; i<100 ; i++)
if ((sorg[i] <= 'z') && (sorg[i] >= 'a'))
dest[i] = sorg[i] + 'A'- 'a';
else
dest[i] = sorg[i];
}
50
M. Rebaudengo, M. Sonza Reorda
Soluzione Assembler
LUNG EQU 100
.MODEL
small
.STACK
.DATA
SORG
DB
LUNG DUP (?)
DEST
DB
LUNG DUP (?)
ST_ADD
DD
DEST
.CODE
...
LEA SI, SORG
LES DI, ST_ADD
51
M. Rebaudengo, M. Sonza Reorda
ciclo:
copia:
52
MOV CX, LUNG
CLD
LODSB
CMP AL, 'z'
JNLE copia
CMP AL, 'a'
JNGE copia
ADD AL, 'A'-'a'
STOSB
LOOP ciclo
...
M. Rebaudengo, M. Sonza Reorda
Istruzioni con operandi
Ogni istruzione per la manipolazione di stringhe ha
un’equivalente istruzione con suffisso S al posto di SB o SW,
nel cui formato compaiono gli operandi.
Formato
MOVS
dest, sorg
CMPS
dest, sorg
SCAS
dest
LODS
sorg
STOS
dest
53
M. Rebaudengo, M. Sonza Reorda
Istruzioni con operandi
(segue)
Le istruzioni di manipolazione di stringhe con operandi si
comportano in modo analogo rispetto alle equivalenti istruzioni
senza operando e vengono tipicamente impiegate per:
• ottenere la selezione automatica dei tipi degli operandi (byte
o word): l’assemblatore è in grado di capire quale
istruzione macchina codificare in base al tipo di dato;
• gestire il caso in cui la stringa sorgente si trovi nel segmento
di dato extra.
54
M. Rebaudengo, M. Sonza Reorda
Istruzioni con operandi
(segue)
Quando la stringa sorgente si trova nel segmento di dato
extra si deve effettuare un segment override nel momento
dell’esecuzione dell’istruzione per la manipolazione di
stringa.
55
M. Rebaudengo, M. Sonza Reorda
Esempio
LUNG
STR1
STR2
56
.MODEL COMPACT
EQU
100
.FARDATA ESEG
DB
LUNG DUP (?)
DB
LUNG DUP (?)
...
.CODE
MOV AX, ESEG
MOV ES, AX
ASSUME ES:ESEG
LEA
SI, ES:STR1
LEA
DI, STR2
MOV
CX, LUNG
CLD
REP
MOVS STR2, ES:STR1
...
M. Rebaudengo, M. Sonza Reorda
Strlen, Strcpy, Strcat
Come esempio di uso delle istruzioni per la manipolazione
di stringhe si riporta il codice generato dal compilatore
Microsoft C 6.0 per le procedure standard C strlen, strcpy e
strcat.
57
M. Rebaudengo, M. Sonza Reorda
Strlen
PUSH
MOV
MOV
MOV
MOV
MOV
XOR
MOV
REPNE
NOT
DEC
XCHG
MOV
POP
RET
58
BP
BP,SP
DX,DI
; salva DI
AX,DS
ES,AX
DI,Word Ptr [BP+04]; puntatore alla stringa
AX,AX
CX,0FFFFH
SCASB
; cerca la fine
CX
CX
AX,CX
; valore di ritorno
DI,DX
BP
M. Rebaudengo, M. Sonza Reorda
PUSH BP
MOV
MOV
MOV
MOV
MOV
MOV
MOV
XOR
MOV
REPNE
NOT
59
Strcpy
BP,SP
DX,DI
BX,SI
SI,Word Ptr [BP+06]
DI,SI
MOV DI,Word Ptr [BP+04]
AX,DS
MOV AX,DI
ES,AX
TEST AL,01
AX,AX
JZ
LAB
CX,FFFF
MOVSB
SCASB
DEC CX
CX
LAB: SHR CX,1
REP MOVSW
ADC CX,CX
REP MOVSB
MOV SI,BX
MOV DI,DX
POP BP
RET
M. Rebaudengo, M. Sonza Reorda
Nota
Se si deve calcolare il numero d'ordine k dell'elemento di
un blocco, che ha causato l'uscita dal ciclo di ripetizione, si
usano le istruzioni
MOV
CX,FFFF
; CX  N
REPNE SCASB
; CX N-k
NOT
CX
; CX N-(N-k)=k
Infatti, eseguire l'istruzione NOT significa sottrarre
l'operando al valore massimo rappresentabile (N=FFFF).
60
M. Rebaudengo, M. Sonza Reorda
Strcat
61
PUSH
MOV
MOV
MOV
MOV
MOV
MOV
XOR
MOV
REPNE
LEA
MOV
MOV
REPNE
NOT
BP
BP,SP
DX,DI
BX,SI
AX,DS
ES,AX
DI,Word Ptr [BP+04]
AX,AX
CX,FFFF
SCASB ; ricerca fine prima stringa
SI,Word Ptr [DI-01]
DI,Word Ptr [BP+06]
CX,FFFF
SCASB ; ricerca fine seconda stringa
CX
M. Rebaudengo, M. Sonza Reorda
Strcat (II)
LAB:
62
SUB
XCHG
MOV
TEST
JZ
MOVSB
DEC
SHR
REP
ADC
REP
MOV
MOV
POP
RET
DI,CX
DI,SI
AX,Word Ptr [BP+04]
SI,0001
LAB
CX
CX,1
MOVSW; copiatura
CX,CX
MOVSB
SI,BX
DI,DX
BP
M. Rebaudengo, M. Sonza Reorda
Scarica

LUNG DUP(?) - Politecnico di Torino