Documente Academic
Documente Profesional
Documente Cultură
LUCRAREA 5
PRELUCRAREA SIRURILOR
UTILIZAREA TABELELOR PENTRU CONVERSII DE CODURI
Transfer pe 8 (16,32) biţi, din zona de memorie indicată de ESI, în zona de memorie indicată
de registrul EDI. După transferul primului byte (word, doubleword), dacă flag-ul DF=0, se petrece
autoincrementarea ESI←ESI+1; EDI←EDI+1 (decrementare pentru DF=1).
Exemplu. Fie dat să copiem 20 de cuvinte duble din şirul sursă source în şirul destinaţie target:
.data
source DWORD 20 DUP(0FFFFFFFFh)
target DWORD 20 DUP(?)
.code
cld ; direction = forward
mov ecx,LENGTHOF source ; setam contorul REP
mov esi,OFFSET source ; incarcam ESI cu adresa soursei
mov edi,OFFSET target ; incarcam EDI cu adresa destinaţiei
rep movsd ;copiem cuvinte duble
1
Arhitectura Calculatoarelor (lucrare de laborator 5) 2
Comparare pe 8 (16,32) biţi, din zona de memorie indicată de ESI, cu zona de memorie
indicată de registrul EDI. După compararea primului byte (word, doubleword), dacă flag-ul DF=0, se
petrece autoincrementarea ESI←ESI+1; EDI←EDI+1 (decrementare pentru DF=1).
Exemple:
.data
source DWORD 1234h
target DWORD 5678h
.code
mov esi,OFFSET source
mov edi,OFFSET target
cmpsd ; compare doublewords
ja L1 ; jump if source > target
Dacă comparăm cuvinte multiple:
mov esi,OFFSET source
mov edi,OFFSET target
cld ; direction = forward
mov ecx,LENGTHOF source ; repetition counter
repe cmpsd ; repeat while equal
Prefixul REPE repetă compararea, incrementând ESI şi EDI în mod automat, până când
ECX=0 sau o pereche de cuvinte duble nu va fi egală.
Instrucţiunile compară valoarea din AL/AX/EAX cu byte, word sau doubleword din zona de memorie
indicată de EDI. Instrucţiunile sunt utile la căutarea unui singur element într-un şir.
Exemple:
.data
alpha BYTE "ABCDEFGH",0
.code
mov edi,OFFSET alpha ; incarcam EDI cu adresa
;sirului de scanat
mov al,'F' ; cautam litera F
mov ecx,LENGTHOF alpha ; setam registrul contor
cld ; direction = forward
repne scasb ; repetam pana nu este egal
jnz quit ; iesire daca litera nu a fost gasita
2
Arhitectura Calculatoarelor (lucrare de laborator 5) 3
Instrucţiunile încarcă valoarea din byte, word sau doubleword din memorie idicat de ESI, în
AL/AX/EAX respectiv. Instrucţiunile sunt utile la căutarea unui singur element într-un şir.
Exemplu: Multiplicarea fiecărui element a unui şir cu o constantă.
INCLUDE Irvine32.inc
.data
array DWORD 1,2,3,4,5,6,7,8,9,10 ; test data
multiplier DWORD 10
.code
main PROC
cld ; direction = forward
mov esi,OFFSET array ; sirul sursa
mov edi,esi ; sirul destinatie
mov ecx,LENGTHOF array ; setarea contorului
L1: lodsd ; incarcarea [ESI] in EAX
mul multiplier ; multiplicarea cu constanta
stosd ; copie din EAX in [EDI]
loop L1
exit
main ENDP
END main
Exemplul 1. {Mutarea unui bloc de memorie de la o adresa sursa la o adresa destinație} Vom prezenta o
prima variantă a acestei probleme care nu utilizează intrucţiuni pentru șiruri.
.DATA
sir1 DB 100 DUP(7)
sir2 DB 100 DUP(?)
.CODE
mov esi,OFFSET sir1
mov edi,OFFSET sir2
mov ecx,LENGTHOF sir1
muta: mov al,[esi]
mov [edi],al
inc esi
inc edi
loop muta
.DATA
sir1 byte 100 DUP(7)
sir2 byte 100 DUP(?)
.CODE
mov esi,OFFSET sir1
mov edi,OFFSET sir2
mov cx,LENGTHOF sir1
cld
muta: movsb sir1,sir2
loop muta
3
Arhitectura Calculatoarelor (lucrare de laborator 5) 4
din exemplul 1 se poate rescrie astfel:
rep movsb sir1,sir2
Exemplul 2. {Compararea a doua siruri de octeți} Varianta fără prefix rep este:
.DATA
sir1 byte 'AAAABC'
sir2 byte 'AAAACB'
.CODE
mov esi,OFFSET sir1
mov edi,OFFSET sir2
mov ecx,LENGTHOF sir1
comp: cmpsb sir1,sir2
jne exit
loop comp
exit: nop
Dacă la terminarea secvenței de program avem (zf)=1, atunci șirurile sunt identice, altfel nu sunt
identice.
In varianta cu prefix rep bucla:
compar: cmpsb sir1,sir2
jne ies
loop compar
ies: nop
se inlocuieste cu:
repe cmpsb sir1,sir2
jne exit
exit: nop
Instrucțiunile pentru șiruri sunt in special utilizate pentru prelucrarea șirurilor de caractere. Șirurile de
caractere sunt șiruri de octeți, fiecare octet reprezentând codul unui caracter alfanumeric. In toate
exemplele prezentate până acum, cit si in cele care vor fi prezentate de acum încolo vom folosi pentru
reprezentarea caracterelor alfanumerice codul ASCII.
Dându-se un șir de caractere reprezentat sub forma unui sir de coduri ASCII, se pune problema
stabilirii unei condiții de terminare a șirului. Acest lucru se poate face cel puțin in doua moduri:
prin plasarea la sfârșitul unui sir de caractere a unui caracter special, de exemplu caracterul '$' sau
caracterul nul (cu codul ASCII zero);
prin gestionarea lungimii șirului de caractere respectiv. In acest caz pentru reprezentarea interna a
unui sir de caractere se poate adopta următoarea structura de date:
┌───────────────────────────┐
│ n = numarul de componente │
├───────────────────────────┤
│ caracter 1 │
├───────────────────────────┤
│ . │
│ . │
│ . │
├───────────────────────────┤
│ caracter n │
└───────────────────────────┘
Astfel șirul de caractere 'ABC' va avea următoarea reprezentare interna:
┌───────────────────┐
│ 3 │
├───────────────────┤
│ 'A' │
├───────────────────┤
│ 'B' │
├───────────────────┤
│ 'C' │
└───────────────────┘
Pentru generarea unui sir de caractere cu reprezentarea de mai sus propunem următoarea tehnica:
.DATA
lung DB l1
sir DB 'acesta este un sir'
l1 EQU sizeof sir
4
Arhitectura Calculatoarelor (lucrare de laborator 5) 5
O alta modalitate eleganta ar fi construirea unei macroinstrucțiuni care primește numele unui sir de
caractere si conținutul acestuia si generează reprezentarea interna corespunzătoare acestuia.
Exemplul 3. {Generarea reprezentării interne a unui sir de caractere cu ajutorul unei macroinstrucțiuni}
gen_sir MACRO nume,continut
LOCAL et
l&nume DB et
nume DB continut
et EQU sizeof nume
ENDM
.DATA
gen_sir sir1,<'sirul 1'>
gen_sir sir2,<'sirul 22'>
gen_sir sir3,<'sirul 333'>
Efectul celor trei apeluri consta in generarea variabilelor octet lsir1, lsir2 si lsir3 care contin la initializare
lungimile sirurilor de caractere generate si a variabilelor sir1, sir2 si sir3 care vor contine sirurile de
caractere respective.
Exemplul 4. {Determinarea codului ASCII al unei cifre hexa} Urmatorul program (pe 16 biţi) determina
si afiseaza cifrele hexa sub forma unei secvente de caractere ASCII. Pentru aceasta se foloseste tabela de
conversie asc_tbl care memoreaza codurile ASCII ale tuturor cifrelor hexa.
.DATA SEGMENT
asc_tbl DB '0123456789ABCDEF'
DATA ENDS
CODE SEGMENT
ASSUME cs:CODE, ds:DATA
start: mov ax,DATA
mov ds,ax
mov cx,10h
xor al,al
mov bx,OFFSET asc_tbl
bucl: mov dh,al
xlatb
mov dl,al
mov ah,06h
int 21h
mov al,dh
inc al
loop bucl
mov ax,4c00h
int 21h
CODE ENDS
END start
Un exemplu tipic de conversie intre doua coduri îl oferă circuitele logice combinațiunile. Tehnica
5
Arhitectura Calculatoarelor (lucrare de laborator 5) 6
tabelelor de conversie poate fi folosita pentru simularea software a acestor circuite. In acest caz tabela de
conversie este tocmai tabela de adevăr a circuitului combi național respectiv.
Tehnica tabelelor de conversie se poate folosi si in cazurile in care in funcție de valoarea unei variabile
trebuie determinata o adresa de memorie. Aceasta adresa poate reprezenta adresa unui sir de caractere (a
unui mesaj de eroare spre exemplu), sau adresa unei porțiuni de cod sau a unei proceduri. In acest caz
însă, deoarece reprezentarea unei adrese se face pe 16 biți, pentru realizarea propriu zisă a conversiei nu se
mai poate folosi instrucțiunea xlat.
1. Să se determine răsturnatul pe loc al unui șir de octeţi sau cuvinte. Afișați pe ecran ambele șiruri.
2. Să se numere toate aparitiile secvenţei, de exemplu 'XX', dintr-un șir de octeţi reprezentând un șir
de caractere. Afișati pe ecran șirul și rezultatul.
3. Se considera trei masive sir1, sir2, sir3 fiecare șir de caractere reprezentind o linie de text. Sa se
concateneze textele din aceste șiruri în sir4, separându-le prin un blanc. Afișati pe ecran toate șirurile.
4. Se considera trei masive sir1, sir2, sir3 fiecare șir de caractere reprezentând o linie de text. Sa se
plaseze textele din aceste șiruri în sir4, astfel încât în textul rezultat, blancurile să fie înlocuite cu ‚_’.
Afișati pe ecran toate șirurile.
5. Sa se scrie un macro care primeşte trei adrese de memorie A1, A2, A3, concateneaza sirurile de
caractere incepind de la adresele A1 si A2 in aceasta ordine, depunind rezultatul la adresa A3. blancurile să
fie înlocuite cu ‚@’. Afișati pe ecran toate șirurile.
6. Sa se scrie un macro care primeste doua adrese de memorie A1 si A2 si un caracter CAR si elimina
caracterul CAR din sirul de caractere incepind de la adresa A1, depunind rezultatul incepind de la adresa
A2. Afișați pe ecran ambele șiruri.
8. Sa se scrie un macro care primeşte trei adrese de memorie S1, S2 si S3 și are ca efect stergerea din
șirul de caractere incepind la adresa S1 a primei aparitii a sirului de caractere incepind de la adresa S2, sirul
de caractere rezultat depunindu-se incepind de la adresa S3. Afișați pe ecran toate șirurile.
9. Se considera o tabela ale carei intrari au lungimea de un cuvint. Fiecare intrare este formata din
cinci cimpuri dispuse astfel:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
Sa se scrie un program care afiseaza continutul tabelei sub forma unui sir de linii, pe ficare linie fiind
afisate in hexazecimal continuturile cimpurilor corespunzatoare unei intrari. Spre exemplu, daca tabela
contine doar doua intrari cu structura:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 1 1 │ 1 1 1 0 1 │ 0 1 0 1 │ 0 1 0 │ 0 │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
6
Arhitectura Calculatoarelor (lucrare de laborator 5) 7
│ 1 0 1 │ 0 1 0 0 1 │ 1 0 1 1 │ 0 1 1 │ 1 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
se vor afisa liniile urmatoare:
3 1D 5 2 0
5 09 B 3 1
10. Se considera o tabela ale carei intrari au lungimea de un cuvint. Fiecare intrare poate avea una din
formele urmatoare:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 1 │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
Sa se scrie un program care afiseaza continutul tabelei sub forma unui sir de linii, pe ficare linie fiind
afisate in hexazecimal continuturile cimpurilor corespunzatoare unei intrari. Spre exemplu, daca tabela
contine doar doua intrari cu structura:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 1 1 │ 1 1 0│ 1 0 1 │ 0 1 0 │ 1 0 0 │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│ 1 │ 0 1 0 1 0 │ 0 1 1 0 1 │ 1 0 1 1 1 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
se vor afisa liniile urmatoare:
0 7 6 5 2 4
1 0A 0D 17