CATEGORII DOCUMENTE |
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.
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.
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
; 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
; 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
JZ GATA
SCASB ; Compara (
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) <--- <
TEST
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
XOR
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 |
Vizualizari: 2227
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved