Lavorare con le Stringhe
From UIC
Lavorare con le Stringhe
Contents |
| Infos | |
|---|---|
| Author: | b0nu$ |
| Email: | bonus@numerica.it |
| Website: | |
| Date: | 01/01/2001 (dd/mm/yyyy) |
| Level: |
|
| Language: | Italian |
| Comments: | |
Introduzione
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 dui bye 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.
Le Istruzioni
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:
.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.
Sintassi:
[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.
Esempio:
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
Qeuesta è usata per confrontare due stringhe.
Sintassi:
[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:
.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, altrimenti...
dec di ;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:
.DATA
stringa DB 100 DUP(?)
.CODE
...
...
cld ;direzione dx-->sx
mov ax,'aà ;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 :
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 e 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:
count EQU 100
buffer DB count DUP(?)
inport DW ?
.CODE
...
...
cld ;direzione
mov cx,count ;numero iterazioni
mov di,OFFSET buffer ;puntatore al buffe
mov dx,inport ;numero della porta
rep insb ;carica nel buffer
Si usa CX come contatore del numero di byte/word da trasferire.
Note Finali
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 !!!
Disclaimer
I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.
Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.
Categories: Assembly | B0nu$ | 2001