Sunteți pe pagina 1din 7

Arhitectura Calculatoarelor (lucrare de laborator 5) 1

LUCRAREA 5
PRELUCRAREA SIRURILOR
UTILIZAREA TABELELOR PENTRU CONVERSII DE CODURI

5.1. SCOPUL LUCRARII


Se prezinta probleme legate de prelucrarea in limbaj de asamblare a șirurilor. Pentru aceasta se
recomanda utilizarea instrucțiunilor speciale pentru tratarea șirurilor. Se prezinta de asemenea tehnici
specifice limbajului de asamblare pentru realizarea conversiilor de coduri, bazate pe utilizarea tabelelor de
conversie.

5.2. CHESTIUNI TEORETICE. EXEMPLE SI REZULTATE COMENTATE.


5.2.1. Tratarea șirurilor
În afară de tipurile de bază, există și posibilitatea efectuării unor operații de transfer, sau
operații aritmetice și logice cu șiruri de date (cu informații aflate în zone continue de memorie).
Operațiile pe șiruri pot fi efectuate individual, pentru fiecare cuvânt din șir, sau automat - cu repetare,
numărul de repetări al instrucțiunii fiind dictat de conținutul unui registru contor.
Operațiile tipic efectuate sunt:
 transferul unui șir din zonă sursa în zonă destinaţie;
 comparare între două şiruri;
 căutarea unei valori într-un şir;
 încărcarea acumulatorului cu elementele unui şir;
 citirea unui şir de la un port de intrare;
 scrierea unui şir la un port de ieşire.
Exemple :

Instrucţiunile MOVSB (Move (copy) bytes)


MOVSW (Move (copy) words)
MOVSD (Move (copy) doublewords)

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).

În operaţii cu şiruri sunt utilizate prefixe de repetare:

REP Repetare până ecx>0


REPZ, REPE Repetare până ZF=1 şi ecx>0
REPNZ, REPNE Repetare până ZF=0 şi ecx>0

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

Instrucţiunile CMPSB (Compare bytes)


CMPSW (Compare words)
CMPSD (Compare doublewords)

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 SCASB (SCAS- Scans a string)


SCASW
SCASD

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

Instrucţiunile STOSB (STOS- Store string data)


STOSW
STOSD

Instrucţiunile încarcă valoarea din AL/AX/EAX , în memorie cu offset-ul indicat de EDI.


Incrementarea se petrece conform flag-ului DF (DF=0- incrementarea, DF=1- decrementarea).
Exemplu. Şirul string1 este completat cu valoarea 0FFh.
.data
Count = 100
string1 BYTE Count DUP(?)
.code
mov al,0FFh ; valoarea de de incarcat
mov edi,OFFSET string1 ; EDI cu adresa sirului
mov ecx,Count ; numarul de elemente ale sirului
cld ; direction = forward
rep stosb ; copierea AL in string1

2
Arhitectura Calculatoarelor (lucrare de laborator 5) 3

Instrucţiunile LODSB (LODS- Load Accumulator from String)


LODSW
LODSD

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

Varianta care utilizează instrucţiunea movsb este urmatoarea:

.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

Utilizând prefixul rep bucla:


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.

5.2.2. Utilizarea tabelelor de conversie.


Se considera n entitati si doua coduri binare C1 si C2. De exemplu entitatile pot fi considerate
caracterele alfanumerice, C1 codul ASCII si C2 codul EBCIDIC. Prin conversia unei entitati din codul C1
în codul C2 se intelege determinarea codului entitatii respective in C2 cunoscind codul sau în C1.
Principial, acest lucru se poate realiza astfel: se considera o tabela T numita tabela de conversie, de
dimensiune n. Al k-lea element al tabelei contine codul in C2 al entitatii care are in C1 codul k. Astfel,
fiind dată o entitate cu codul k1 in C1, codul k2 al acesteia in C2 va fi k2=T(k1). C1 se numeste cod sursa
si C2 se numeste cod destinatie.
Limbajul de asamblare conţine o instructiune ce permite efectuarea rapidă a conversiei de cod între
două coduri ce implica cel mult 256 de entitati, adică codificarea se face pe cel mult 8 biti. Aceasta este
instructiunea xlat, cu sintaxa urmatoare:
xlat OPR (al) <-- ((bx)+(al))
xlatb
Astfel daca registrul bx contine adresa de inceput a tabelei de conversie si registrul al contine codul
unei entitati in codul sursa, dupa executarea instructiunii xlat, in al se va obtine codul entitatii in codul
destinatie.

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.

5.3. PROBLEME PROPUSE (Utilizați macros și proceduri)


Toate programele din exemple să fie rulate pas cu pas în debugger.

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.

7. Sa se scrie un macro care primeste:


 doua adrese S1 si S2 reprezentind adresele a doua siruri de caractere;
 doua numere intregi I si J care satisfac relatia 1, ..., I, ..., J, ,,,, N , lungimea sirului de caractere
incepind de la adresa S1;
si depune începând de la adresa S2 subsirul sirului de caractere incepind de la adresa S1 cuprins intre
pozitiile I si J ale acestuia. 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

5.4. CONTINUTUL REFERATULUI


1. Programele corespunzatoare exemplelor (.asm), care au fost utilizate la elaborarea sarcinii
individuale (maxim 3 exemple).
2. Programele .asm elaborate si comentate conform sarcinii individuale.

5.5 Sarcină pentru lucrul neauditorial


Subiecte pentru evaluarea pregătirii către lucrarea de laborator 6: Modul de apelare a unei funcţii
BIOS.

S-ar putea să vă placă și