Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateC
C sharpCalculatoareCorel drawDot netExcelFox pro
FrontpageHardwareHtmlInternetJavaLinux
MatlabMs dosPascalPhpPower pointRetele calculatoare
SqlTutorialsWebdesignWindowsWordXml

Instructiuni pentru operatii cu siruri de caractere / cuvinte

calculatoare



+ Font mai mare | - Font mai mic



Instructiuni pentru operatii cu siruri de caractere / cuvinte

Acest grup de instructiuni implementeaza un set puternic de operatii cu siruri de octeti sau de cuvant. Prin sir se intelege o secventa de octeti sau de cuvinte, aflate la adrese succesive de memorie. Setul de instructiuni cuprinde operatii primitive (la nivel de un octet sau un cuvant) si prefixe de repetare, care pot realiza repetarea operatiilor primitive de un numar fix de ori sau pana la indeplinirea unei conditii de tip comparatie.



1 Operatii primitive

Operatiile primitive se grupeaza in patru categorii, fiecare putand fi pe octet sau pe cuvant. Denumirea instructiunilor la nivel de octet se termina cu litera B, iar a celor la nivel de cuvant cu litera W. Aceste instructiuni nu au operanzi.

. Move String (Copiaza sir) MOVSB, MOVSW

. Compare String (Compara siruri) CMPSB, CMPSW

. Load String (Incarca sir in AL / AX) LODSB, LODSW

. Store String (Depune AL / AX in sir) STOSB, STOSW

. Scan String (Compara sir cu AL / AX) SCASB, SCASW

Toate operatiile primitive folosesc registrele DS:SI ca adresa sursa si / sau ES:DI ca adresa destinatie. De asemenea, toate operatiile primitive actualizeaza adresele implicate in operatie, in felul urmator:

. daca flagul DF = 0, adresele (registrul SI si / sau DI) sunt incrementate cu 1 sau cu 2, dupa cum operatia primitiva este la nivel de octet sau de cuvant;

. daca flagul DF = 1, adresele (registrul SI si / sau DI) sunt decrementate cu 1sau cu 2, dupa cum operatia primitiva este la nivel de octet sau de cuvant. Vom utiliza notatiile:

(SI) <- (SI) + delta

(DI) <- (DI) + delta

unde delta este 1 sau 2, dupa starea bistabilului DF sau a tipului operatiei (octet sau cuvant).

Starea flagului DF poate fi controlata prin instructiunile (fara operanzi) CLD (Clear Direction) si STD (Set Direction), care sterg, respectiv seteaza acest bistabil.

Instructiunile MOVSB, MOVSW

Semnificatia este:

(ES:DI) <- ((DS:SI))

(SI) <- (SI) + delta

(DI) <- (DI) + delta

Se transfera deci un octet (MOVSB) sau un cuvant (MOVSW) de la adresa data de (DS:SI) la adresa data de (ES:DI), dupa care se actualizeaza adresele.

Instructiunile CMPSB, CMPSW

Semnificatia este:

((DS:SI) - ((ES:DI))

(SI) <- (SI) + delta

(DI) <- (DI) + delta

Se calculeaza temporar (fara a se modifica vreun operand) diferenta dintre octetii (cuvintele) de la adresele (DS:SI) si (ES:DI), dupa care se actualizeaza adresele. Bistabilii de conditie se pozitioneaza conform operatiei de scadere. Instructiunile se folosesc la testarea egalitatii / inegalitatii sirurilor.

Instructiunile LODSB, LODSW

Semnificatia este:

(acumulator) <- ((DS:SI))

(SI) <- (SI) + delta

Se incarca deci in AL, respectiv AX, octetul, respectiv cuvantul de la adresa (DS:SI), dupa care se actualizeaza aceasta adresa.

Instructiunile STOSB, STOSW

Semnificatia este:

((ES:DI ) <- (acumulator)

(DI) <- (DI) + delta

Se depune continutul registrului AL, respectiv AX in octetul, respectiv cuvantul de la adresa (ES:DI), dupa care se actualizeaza aceasta adresa.

Instructiunile SCASB, SCASW

Semnificatia este:

(acumulator) - ((ES:DI))

(DI) <- (DI) + delta

Se calculeaza temporar (fara a se modifica vreun operand) diferenta dintre registrul AL, respectiv AX si octetul, respectiv cuvantul de la adresa (ES:DI), dupa care se actualizeaza aceasta adresa. Bistabilii de conditie se pozitioneaza conform operatiei de scadere. Instructiunile se folosesc la testarea / cautarea unui anumit octet (cuvant intr-un sir).

Pe langa formele fara operanzi, descrise mai sus, asamblorul mai recunoaste si forme in care operanzii apar explicit. Semnificatia adreselor implicate in aceste instructiuni nu poate fi insa schimbata (se vor folosi tot registrele SI si DI). ;

Singura ratiune pentru aceste forme este specificarea unui prefix de segment pentru adresa sursa. In acest caz, mnemonica instructiunii se scrie fara litera B sau W de la sfarsit, dar este obligatorie specificarea tipului operatiei prin operatorul PTR. Nu se recomanda utilizarea acestor prefixe de segment din urmatoarele motive:

. nu se poate schimba registrul de segment al adresei destinatie (acesta este tot timpul ES);

. in conditiile folosirii prefixelor de repetare (vezi 2), instructiunea rezultata ar avea atat prefix de repetare, cat si prefix de segment, ceea ce poate conduce ta functionari defectuoase, intr-un context in care pot aparea intreruperi externe.

2 Prefixe de repetare (REP / REPE / REPZ, REPNE / REPNZ)

Prefixele de repetare permit executia repetata a unei operatii primitive cu siruri de octeti sau de cuvinte, functie de un contor de operatii sau de un contor si o conditie logica. Aceste prefixe nu sunt instructiuni in sine, ci participa la formarea unor instructiuni compuse, alaturi de operatiile primitive descrise mai sus.

Prefixul de repetare REP / REPE / REPZ (Repeat - Repeta)

Cele trei mnemonice identifica de fapt un unic prefix de repetare. Forma generala a unei instructiuni cu acest prefix este:

REP / REPE / REPZ op_primitiva

Semnificatia este:

cat timp CX != 0

Se vede, deci, ca operatia primitiva se executa de un numar maxim de ori dat de continutul registrului CX. Daca CX este initial 0, operatia nu se executa nici o data. In cazul operatiilor primitive CMPS si SCAS (care pozitioneaza ZF), se iese fortat din bucla daca

ZF = 0, adica daca rezultatul operatiei primitive este nenul. Bucla se executa deci cat timp acest rezultat este 0.

De obicei, scrierea cu REP se foloseste la primitivele de tip MOVS, LODS si STOS, iar scrierea cu REPE sau REPZ la primitivele de tip CMPS si SCAS.

Sa consideram doua exemple.

Secventa de mai jos transfera 100 de octeti de la adresa SURSA la adresa DESTINATIE, ambele presupuse in segmentul curent adresat prin DS.

.data

SURSA db 100 dup (?)

DEST db 100 dup (?)

.code

CLD  ; Directie ascendenta

MOV  AX, DS ; Pregatire

MOV  ES, AX ; Adrese

LEA  SI, SURSA ; Adresa sursa

LEA  DI, DEST ; Adresa destinatie

MOV  CX, 100 ; Contor

REP  MOVSB ; Instructiune compusa

Secventa urmatoare identifica primul octet diferit de un octet dat dintr-un sir de lungime 200 de octeti.

.data

SIR DB 200 dup (?)

.code

MOV  AX, DS

MOV  ES, AX

LEA  DI, SIR

CLD

MOV  AL, 'A' ; Se cauta primul octet

; diferit de 'A'

MOV  CX, 200 ; Numar maxim de iteratii

REPE SCASB ; Bucla de cautare

Examinand bistabilul ZF la iesirea din aceasta secventa putem deduce rezultatul cautarii. Daca ZF = 0 inseamna ca a avut loc o iesire fortata din bucla, deci comparatia a dat rezultatul 0. Registrul Dl, decrement cu o unitate, furnizeaza adresa primului octet diferit de octetul din AL. Daca F = 1, inseamna ca toti octetii parcursi sunt identici cu octetul dat in AL.

La prima vedere, s-ar parea ca, la fel de bine, am putea examina continutul registrului CX la iesirea din bucla (0 sau diferit de 0), pentru a deduce daca octetul cautat a fost identificat sau nu. Acest test este incorect, deoarece s-ar putea ca primul octet diferit de cel din AL sa fie chiar ultimul. In acest caz, se iese din bucla cu CX = 0, la fel ca in situatia in care toti octetii parcursi sunt identici cu cel din AL.

Prefixul de repetare REPNE / REPNZ (Repeat While Not Equal / Not Zero - Repeta cat timp diferit / diferit de zero)

Cele doua mnemonice identifica un singur prefix de repetare. Forma generala este:

REPNE/REPNZ operatie_primitiva

Semnificatia este:

cat timp CX != 0

Diferenta fata de prefixul precedent este conditia de iesire fortata din bucla: se iese daca ZF = 1, deci daca rezultatul operatiei primitive a fost 6. Ca atare, bucla se executa cat timp acest rezultat este nenul, dar nu mai mult de CX ori.

Practic, acest prefix de repetare se foloseste numai cu operatiile primitive CMPS si SCAS. Pentru celelalte operatii primitive, in care nu se ia in considerare bistabilul ZF, se prefera scrierea cu prefixul REP. La iesirea din bucla, se poate examina bistabilul ZF, deducandu-se daca a fost sau nu o iesire fortata.

Urmatoarea secventa determina ultimul caracter egal cu un caracter dat, prin parcurgerea sirului in sens invers.

.data

SIR db 30 (?)

.code

LEA  DI, SIR

ADD  DI, 29

MOV  CX, 30

STD

MOV AL, '?' ; Se cauta primul octet = 'x', de

; la dreapta la stanga

REPNE SCASB

3 Operatii complexe asupra sirurilor

Sa consideram unele operatii complexe asupra sirurilor de caractere. Vom considera ca sirurile au, ca ultim caracter, octetul 0, pe post de terminator de sir.

Compararea lexicografica a doua siruri

Acest algoritm primeste ca date de intrare adresele a doua siruri de caractere terminate cu 0 si intoarce diferenta primilor octeti care difera in cele doua siruri sau 0 daca cele doua siruri coincid. Urmatoarea secventa de program intoarce in AL rezultatul cerut. (Presupunem ca DS si ES sunt initializate corespunzator.)

.data

SIR_1 DB 'Un exemplu de sir terminat cu zero', 0

SIR_2 DB 'Un exemplu de sir terminat cu octetul nul', 0

.code

CLD

LEA  SI, SIR_1

LBA  DI, SIR_2

IAR:

LODSB  ; (AL) = (SIR_1)

TEST AL, AL ; Test terminator

JZ  GATA

SCASB  ; Compara (AL) cu (SIR_2)

JE  IAR ; Daca sunt egale, se reia bucla

DEC  DI ; Daca nu, se revine pe caracterul

GATA: ; anterior

SUB  AL, ES: [DI] ; Se face diferenta

Copierea unui sir in alt sir

Urmatoarea secventa copiaza un sir in alt sir. Copierea inceteaza dupa copierea terminatorului din sirul sursa. Se presupune ca la adresa destinatie se gaseste suficient spatiu rezervat. Se presupune ca registrele DS si ES indica segmentul curent de date.

.data

SURSA DB 'Un sir care trebuie copiat', 0

DEST DB 80 DUP (?)

.code

LEA  SI, SURSA

LEA  DI, DEST

CLD

BUCLA:

LODSB  ; (AL) <--- (SURSA)

STOSB  ; (DEST) <--- <AL)

TEST AL,AL ; Test terminator

JNZ  BUCLA ; Reluare

Calculul lungimii unui sir

Urmatoarea secventa determina in AX numarul de caractere utile din sirul SURSA. Terminatorul 0 nu se numara,

.code

CLD

LEA  DI, SURSA

MOV  CX, 0FFFFH ; Numarul maxim posibil

MOV BX, DI ; Salvare adresa inceput

XOR  AL, AL ; Octet cautat

REPNZ SCASB ; Repeta cat timp e

; diferit de 0

DEC  DI ; inapoi pe terminator

SUB  DI, BX ; Adresa terminator - Adresa de

MOV  AX, DI ; inceput = Lungime

Copierea a N caractere dintr-un sir in alt sir

Se copiaza un numar de N caractere din sirul SURSA in sirul DEST. Daca SURSA are mai putin de N caractere, se completeaza DEST cu 0, pana la N caractere.

.code

CLD

LEA  SI, SURSA

LEA  DI, DEST

MOV  CX, N

OR  CX, CX

JZ  GATA

BUCLA:

LODSB ; Bucla de copiere

STOSB ; pana la terminator

DEC CX ; inclusiv, dar nu mai

JZ GATA ; mult de CX

TEST AL, AL ; caractere

JNZ BUCLA

REP STOSB ; Completare eventual cu 0

GATA:

Daca N este 0, nu se copiaza nimic. Se executa o bucla de copiere, in care se decrementeaza CX. Daca CX = 0, totul se termina. Daca s-a copiat terminatorul, se iese din bucla de copiere. In acest moment, AL = 0 si, daca CX > 0, se executa depunerea lui AL in DEST, de atatea ori cat este valoarea curenta a lui CX.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 2255
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved