You are on page 1of 57

3

INTRODUCERE N LIMBAJUL DE ASAMBLARE INTEL


3.1 Elementele arhitecturale de baz ale microprocesorului Intel Ne vom referi n cele ce urmeaz la familia de microprocesoare intitulat Intel iAPx86 ce stau la baza calculatoarelor IBM PC, ncepnd de la procesoarele 8088 i 8086, continund cu 80286, 80386, 80486, Pentium, .a.m.d. Procesorul 8086 reprezint, de fapt, baza familiei ce este cunoscut pe scurt sub denumirea de familia microprocesoarelor x86. De aceea se vor face referiri n continuare la aceast arhitectur (8086).

3.1.1 Regitrii microprocesorului Intel Regitrii (sau registrele) microprocesorului reprezint locaii de memorie speciale aflate direct pe cip; din aceast cauz reprezint cel mai rapid tip de memorie. Alt lucru deosebit legat de regitri este faptul c fiecare dintre acetia au un scop bine precizat, oferind anumite funcionaliti speciale, unice. Exist patru mari categorii de regitri: regitrii de uz general, registrul indicatorilor de stare (flags), regitrii de segment i registrul pointer de instruciune.

Elemente de arhitectur a sistemelor de calcul i operare

Fig. 3.1 Regitrii de uz general acumulator, index de baz, contor i de date

3.1.1.1 Regitrii de uz general Regitrii de uz general (figura 3.1 i figura 3.2) sunt implicai n operarea majoritii instruciunilor, drept operanzi surs sau destinaie pentru calcule, copieri de date, pointeri la locaii de memorie sau cu rol de contorizare. Fiecare dintre cei 8 regitrii de uz general AX, BX, CX, DX, SP, BP, DI,SI sunt regitrii pe 16 bii pentru microprocesorul 8086, iar de la procesorul 80386 ncoace au devenit regitrii pe 32 de bii, denumii, respectiv: EAX, EBX, ECX, EDX, ESP, EBP, EDI, ESI (litera E provine de la Extended extins n englez). Mai mult, cei mai puin semnificativi 8 bii ai regitrilor AX, BX, CX, DX formeaz respectiv regitrii AL, BL, CL, DL (litera L provine de la Low jos n englez), iar cei mai semnificativi 8 bii

Introducere n limbajul de programare Intel

ai acelorai regitrii formeaz regitrii AH, BH, CH, DH (litera H provine de la High nalt n englez) (figura 3.1).

Fig. 3.2 Regitrii de uz general index i pointer

Ne vom concentra n continuare atenia asupra regitrilor generali pe 16 bii; fiecare dintre acetia poate stoca o valoare pe 16 bii, poate fi folosit pentru stocarea unei valori din memorie sau poate fi utilizat pentru operaii aritmetice i logice. Spre exemplu, urmtoarele instruciuni: MOV BX, 2 MOV DX, 3 ADD BX, DX ncarc valoarea 2 n registrul BX, valoarea 3 n registrul DX, adun cele dou valori iar rezultatul (5) este memorat n registrul BX. n exemplul anterior putem utiliza oricare dintre regitrii de uz general n locul regitrilor BX i DX. n afara proprietii de a stoca valori i de a folosi drept operanzi surs sau destinaie pentru instruciunile de manipulare a datelor, fiecare

Elemente de arhitectur a sistemelor de calcul i operare

dintre cei opt regitri de uz general au propria personalitate. Vom vedea n continuare care sunt caracteristicile specifice fiecruia dintre regitrii de uz general. Registrul AX (EAX) Registrul AX (EAX) este denumit i registrul acumulator, fiind principalul registru de uz general utilizat pentru operaii aritmetice, logice i de deplasare de date. Totdeauna operaiile de nmulire i mprire presupun implicarea registrului AX. Unele dintre instruciuni sunt optimizate pentru a se executa mai rapid atunci cnd este folosit AX. n plus, registrul AX este folosit i pentru toate transferurile de date de la/ctre porturile de Intrare/Ieire. Poate fi accesat pe poriuni de 8, 16 sau 32 de bii, fiind referit drept AL (cei mai puin semnificativi 8 bii din AX), AH (cei mai semnificativi 8 bii din AX), AX (16 bii) sau EAX (32 de bii). Prezentm n continuare alte cteva exemple de instruciuni ce utilizeaz registrul AX. De remarcat este faptul c transferurile de date se fac pentru instruciunile (denumite i mnemonice) Intel de la dreapta spre stnga, exact invers dect la Motorola (vom vedea i alt exemplu asemntor la scrierea datelor n memorie sub format diferit la Motorola fa de Intel), unde transferul se face de la stnga la dreapta. Instruciunea: MOV AX, 1234H ncarc valoarea 1234H (4660 n zecimal) n registrul acumulator AX. Dup cum spuneam, cei mai puini semnificativi 8 bii ai registrului AX sunt identificai de AL (A-Low) iar cei mai semnificativi 8 bii ai aceluiai registru sunt identificai ca fiind AH (A-High). Acest lucru este utilizat pentru a lucra cu date pe un octet, permind ca registrul AX s fie folosit pe postul a doi regitri separai (AH i AL). Aceeai regul este valabil i pentru regitrii de uz general BX, CX, DX. Urmtoarele trei instruciuni seteaz registrul AH cu valoarea 1, incrementeaz cu 1 aceast valoare i apoi o copiaz n registrul AL: MOV AH, 1 INC AH MOV AL, AH Valoarea final a registrului AX va fi 22 (AH = AL = 2).

Introducere n limbajul de programare Intel

Registrul BX (EBX) Registrul BX (Base), sau registrul de baz poate stoca adrese pentru a face referire la diverse structuri de date, cum ar fi vectorii stocai n memorie. O valoare reprezentat pe 16 bii stocat n registrul BX poate fi utilizat ca fiind o poriune din adresa unei locaii de memorie ce va fi accesat. Spre exemplu, urmtoarele instruciuni ncarc registrul AH cu valoarea din memorie de la adresa 21. MOV AX, 0 MOV DS, AX MOV BX, 21 MOV AH, [ BX ] Se observ c am ncrcat valoarea 0 n registrul DS nainte de a accesa locaia de memorie referit de registrul BX. Acest lucru este datorat segmentrii memoriei (segmentare discutat mai n detaliu n seciunea consacrat regitrilor de segment); implicit, atunci cnd este folosit ca pointer de memorie, BX face referire relativ la registrul de segment DS (adresa la care face referire este o adres relativ la adresa de segment coninut n registrul DS). Registrul CX (ECX) Specializarea registrului CX (Counter) este numrarea; de aceea, el se numete i registrul contor. De asemenea, registrul CX joac un rol special atunci cnd se folosete instruciunea LOOP. Rolul de contor al registrului CX se observ imediat din exemplul urmtor: MOV CX, 5 start: <instruciuni ce se vor executa de 5 ori> SUB CX, 1

Elemente de arhitectur a sistemelor de calcul i operare

JNZ start Deoarece valoarea iniial a lui CX este 5, instruciunile cuprinse ntre eticheta start i instruciunea JNZ se vor executa de 5 ori (pn cnd registrul CX devine 0). Instruciunea SUB CX, 1 decrementeaz registrul CX cu valoarea 1 iar instruciunea JNZ start determin saltul napoi la eticheta start dac CX nu are valoarea 0. n limbajul microprocesorului exist i o instruciune special legat de ciclare. Aceasta este instruciunea LOOP, care este folosit n combinaie cu registrul CX. Liniile de cod urmtoare sunt echivalente cu cele anterioare, dar aici se utilizeaz instruciunea LOOP: MOV CX, 5 start: <instruciuni ce se vor executa de 5 ori> LOOP start Se observ c instruciunea LOOP este folosit n locul celor dou instruciuni SUB i JNZ anterioare; LOOP decrementeaz automat registrul CX cu 1 i execut saltul la eticheta specificat (start) dac CX este diferit de zero, totul ntr-o singur instruciune. Registrul DX (EDX) Registrul de uz general DX (Data register), denumit i registrul de date, poate fi folosit n cazul transferurilor de date Intrare/Ieire sau atunci cnd are loc o operaie de nmulire sau de mprire. Instruciunea IN AL, DX copiaz o valoare de tip Byte dintr-un port de intrare, a crui adres se afl n registrul DX. Urmtoarele instruciuni determin scrierea valorii 101 n portul I/O 1002: ... MOV AL, 101

Introducere n limbajul de programare Intel

MOV DX, 1002 OUT DX, AL Referitor la operaiile de nmulire i mprire, atunci cnd mprim un numr pe 32 de bii la un numr pe 16 bii, cei mai semnificativi 16 bii ai dempritului trebuie s fie n DX. Dup mprire, restul mpririi se va afla n DX. Cei mai puin semnificativi 16 bii ai dempritului trebuie s fie n AX iar ctul mpririi va fi n AX. La nmulire, atunci cnd se nmulesc dou numere pe 16 bii, cei mai semnificativi 16 bii ai produsului vor fi stocai n DX iar cei mai puin semnificativi 16 bii n registrul AX. Registrul SI Registrul SI (Source Index) poate fi folosit, ca i BX, pentru a referi adrese de memorie. De exemplu, secvena de instruciuni urmtoare: MOV AX, 0 MOV DS, AX MOV SI, 33 MOV AL, [ SI ] ncarc valoarea (pe 8 bii) din memorie de la adresa 33 n registrul AL. Registrul SI este, de asemenea, foarte folositor atunci cnd este utilizat n legtur cu instruciunile dedicate tipului STRING (ir de caractere). Secvena urmtoare : ... CLD MOV AX, 0 MOV DS, AX MOV SI, 33 LODSB ...

Elemente de arhitectur a sistemelor de calcul i operare

nu numai c ncarc registrul AX cu valoarea de la adresa de memorie referit de registrul SI, dar adun, de asemenea, valoarea 1 la SI. Acest lucru este deosebit de eficient atunci cnd se acceseaz secvenial o serie de locaii de memorie, cum ar fi irurile de caractere. Instruciunile de tip STRING se pot repeta de mai multe ori, astfel nct o singur instruciune poate avea ca efect sute sau mii de operaii. Registrul DI Registrul DI (Destination Index) este utilizat n mod asemntor registrului SI. n secvena de instruciuni urmtoare: ... MOV AX, 0 MOV DS, AX MOV DI, 1000 ADD BL, [ DI ] se adun la registrul BL valoarea pe 8 bii stocat la adresa 1000. Registrul DI este puin diferit fa de registrul SI n cazul instruciunilor de tip string; dac SI este ntotdeauna pe post de pointer surs de memorie, registrul DI servete drept pointer destinaie de memorie. Mai mult, n cazul instruciunilor de tip string, registrul SI adreseaz memoria relativ la registrul de segment DS, n timp ce DI conine referiri la memorie relativ la registrul de segment ES. n cazul n care SI i DI sunt utilizai cu alte instruciuni, ei fac referire la registrul de segment DS. Registrul BP Pentru a nelege mai bine rolul regitrilor BP i SP, a sosit momentul s spunem cteva lucruri despre poriunea de memorie denumit stiv (n englez stack). Stiva (figura 3.3) reprezint o poriune special de locaii adiacente din memorie. Aceasta este coninut n cadrul unui segment de memorie i identificat de un selector de segment memorat n registrul SS (cu excepia cazului n care se folosete modelul nesegmentat de memorie n care stiva poate fi localizat oriunde n spaiul de adrese liniare al programului). Stiva este o poriune a memoriei unde valorile pot fi stocate

Introducere n limbajul de programare Intel

i accesate pe principul LIFO (Last In First Out), drept urmare ultima valoare stocat n stiv este prima ce va fi citit din stiv. De regul, stiva este utilizat la apelul unei proceduri sau la ntoarcerea dintr-un apel de procedur (principalele instruciuni folosite sunt CALL i RET).

Fig. 3.3 Structura stivei

Registrul pointer de baz, BP (Base Pointer) poate fi utilizat ca pointer de memorie precum regitrii BX, SI i DI. Diferena este aceea c, dac BX, SI i DI sunt utilizai n mod normal ca pointeri de memorie relativ la segmentul DS, registrul BP face referire relativ la segmentul de stiv SS. Principiul este urmtorul: o modalitate de a trece parametrii unei subrutine este aceea de a utiliza stiva (acest lucru se ntmpl n mod obinuit n limbajele de nivel nalt, C sau Pascal, spre exemplu). Dac stiva se afl n poriunea de memorie referit de registrul de segment SS (Stack Segment), datele se afl n mod normal n segmentul de memorie referit de ctre DS, registrul segment de date. Deoarece BX, SI i DI se refer la segmentul de date, nu exist o modalitate eficient de a folosi regitrii BX, SI, DI pentru a face referire la parametrii salvai n stiv din cauz c stiva este localizat ntr-un alt segment de memorie. Registrul BP ofer

Elemente de arhitectur a sistemelor de calcul i operare

rezolvarea acestei probleme asigurnd adresarea n segmentul de stiv. Spre exemplu, instruciunile: ... PUSH BP MOV BP, SP MOV AX, [ BP+4 ] fac s se acceseze segmentul de stiv pentru a ncrca registrul AX cu primul parametru trimis de un apel C unei rutine scrise n limbaj de asamblare. n concluzie, registrul BP este conceput astfel nct s ofere suport pentru accesul la parametri, variabile locale i alte necesiti legate de accesul la poriunea de stiv din memorie. Registrul SP Registrul SP (Stack Pointer), sau pointerul de stiv, reine de regul adresa de deplasament a urmtorului element disponibil n cadrul segmentului de stiv. Acest registru este, probabil, cel mai puin general dintre regitrii de uz general, deoarece este dedicat mai tot timpul administrrii stivei. Registrul BP face n fiecare clip referire la vrful stivei acest vrf al stivei reprezint adresa locaiei de memorie n care va fi introdus urmtorul element n stiv. Aciunea de a introduce un nou element n stiv se numete mpingere (n englez push); de aceea, instruciunea respectiv poart numele de PUSH. n mod asemntor, operaia de scoatere a unui element din vrful stivei poart, n englez, numele de pop, iar instruciunea echivalent operaiei se numete POP. n figurile 3.4 i 3.5 sunt ilustrate modificrile survenite n coninutul stivei i al regitrilor SP, BX i CX ca urmare a execuiei instruciunilor urmtoare (se presupune c registrul SP are iniial valoarea 1000): ... MOV BX, 9 PUSH BX MOV CX, 10 PUSH CX

Introducere n limbajul de programare Intel

POP BX POP CX ... Este permis stocarea valorilor n registrul SP precum i modificarea valorii sale prin adunare sau scdere la fel ca i n cazul celorlali regitri de uz general; totui, acest lucru nu este recomandat dac nu suntem foarte siguri de ceea ce facem. Prin modificarea registrului SP, vom modifica adresa de memorie a vrfului stivei, ceea ce poate avea efecte neprevzute, aceasta pentru c instruciunile PUSH i POP nu reprezint unicele modaliti de utilizare a stivei. Indiferent dac apelm o subrutin sau ne ntoarcem dintr-un astfel de apel de subrutin, fie procedur sau funcie, n acest caz este folosit stiva. Unele resurse de sistem, precum tastatura sau ceasul de sistem, pot folosi stiva n momentul trimiterii unei ntreruperi la microprocesor. Acest lucru presupune c stiva este folosit continuu, deci dac se modific registrul SP (adic adresa stivei), datele din noile locaii de memorie nu vor mai fi cele corecte. n concluzie, registrul SP nu trebuie modificat n mod direct; el este modificat automat n urma instruciunilor POP, PUSH, CALL, RET. Oricare dintre ceilali regitri de uz general pot fi modificai n mod direct n orice moment.

Elemente de arhitectur a sistemelor de calcul i operare

Fig. 3.4 Modalitatea de funcionare a stivei dup execuia primelor patru instruciuni

Introducere n limbajul de programare Intel

Fig. 3.5 Funcionarea stivei dup ultimile dou instruciuni POP

3.1.1.2 Registrul pointer de instruciuni (IP) Registrul pointer de instruciuni (IP Instruction Pointer, vezi figura 3.6) este folosit, ntotdeauna, pentru a stoca adresa urmtoarei instruciuni ce va fi executat de ctre microprocesor. Pe msur ce o instruciune este executat, pointerul de instruciune este incrementat i se va referi la urmtoarea adres de memorie (unde este stocat urmtoarea instruciune ce va fi executat). De regul, instruciunea ce urmeaz a fi executat se afl la adresa imediat urmtoare instruciunii ce a fost executat, dar exist i cazuri speciale (rezultate fie din apelul unei subrutine prin instruciunea CALL, fie prin ntoarcerea dintr-o subrutin, prin instruciunea RET). Pointerul de instruciuni nu poate fi modificat sau citit n mod direct; doar instruciuni speciale pot ncrca acest registru cu o nou valoare. Registrul pointer de instruciune nu specific pe de-a ntregul adresa din memorie a urmtoarei instruciuni ce va fi executat, din aceeai cauz a segmentrii memoriei. Pentru a aduce o instruciune din memorie, registrul CS ofer o adres de baz iar registrul pointer de instruciune indic adresa de deplasament plecnd de la aceast adres de baz.

Elemente de arhitectur a sistemelor de calcul i operare

Fig. 3.6. Regitrii de segment, pointerul de instruciuni i registrul indicatorilor de stare

Introducere n limbajul de programare Intel

3.1.1.3 Registrul indicatorilor de stare (FLAGS)

Fig. 3.7 Registrul indicatorilor de stare - detaliu

Registrul indicatorilor de stare (FLAGS) pe 16 bii conine informaii legate de starea microprocesorului precum i de rezultatele ultimilor instruciuni executate. Un indicator de stare (flag) este n sine o locaie de memorie de 1 bit ce indic starea curent a microprocesorului i modalitatea sa de operare. Un indicator se spune c este setat dac are valoarea 1 i nu este setat n caz contrar. Indicatorii de stare se modific dup execuia unor instruciuni aritmetice sau logice. Exemple de indicatori de stare (vezi figura 3.7): - C (Carry) indic apariia unei cifre binare de transport n cazul unei adunri sau mprumut n cazul unei scderi; - O (Overflow) apare n urma unei operaii aritmetice. Dac este setat, nseamn c rezultatul nu ncape n operandul destinaie; - Z (Zero) indic faptul c rezultatul unei operaii aritmetice sau logice este zero; - S (Sign) indic semnul rezultatului unei operaii aritmetice;

Elemente de arhitectur a sistemelor de calcul i operare

- D (Direction) cnd este zero, procesarea elementelor irului se face de la adresa mai mic la cea mai mare, n caz contrar este invers; - I (Interrupt) controleaz posibilitatea microprocesorului de a rspunde la evenimente externe (apeluri de ntrerupere); - T (Trap) este folosit de programele de depanare (de tip debugger), activnd sau nu posibilitatea execuiei programului pas cu pas. Dac este setat, UCP ntrerupe fiecare instruciune, lsnd programul depanator s execute programul respectiv pas cu pas; - A (Auxiliary carry) suport operaii n codul BCD. Majoritatea programelor nu ofer suport pentru reprezentarea numerelor n acest format, de aceea se utilizeaz foarte rar; - P (Parity) este setat n conformitate cu paritatea biilor cei mai puin semnificativi ai unei operaii cu date. Astfel, dac rezultatul unei operaii conine un numr par de bii 1, acest indicator este setat. Dac numrul de bii 1 din rezultat este impar, atunci indicatorul PF este zero. Este folosit de regul de programe de comunicaii, dar Intel a introdus acest indicator nu pentru a ndeplini o anumit funcionalitate, ci pentru a asigura compatibilitatea cu vechile microprocesoare ale familiei x86. 3.1.1.4 Regitrii de segment Proprietile regitrilor de segment (figura 3.6) sunt n strns legtur cu noiunea de segmentare a memoriei. Premisa de la care se pleac este urmtoarea: 8086 este capabil s adreseze 1MB de memorie, astfel c sunt necesare adrese pe 20 de bii pentru a cuprinde toate locaiile din spaiul de 1 MB de memorie. Totui, registrele utilizate sunt registre pe 16 bii, deci a trebuit s se gseasc o soluie pentru aceast problem. Soluia gsit se numete segmentarea memoriei; n acest caz memoria de 1MB este mprit n 16 segmente de cte 64 KB (16*64 KB = 1024 KB = 1 MB). Noiunea de segmentare a memoriei presupune utilizarea unor adrese de memorie formate din dou pri. Prima parte reprezint adresa segmentului iar cea de-a doua poriune reprezint adresa de deplasament, sau offset-ul (figura 3.8).

Introducere n limbajul de programare Intel

Fig. 3.8 Cele dou poriuni ale unei adrese segmentate

Fiecare pointer de memorie pe 16 bii este combinat cu coninutul unui registru de segment pe 16 bii pentru a forma o adres complet pe 20 de bii. Adresa de segment mpreun cu adresa de deplasament sunt combinate n felul urmtor: valoarea de segment este deplasat la stnga cu 4 bii (nmulit cu 16 = 24) i apoi adunat cu valoarea adresei de deplasament. Adresa astfel construit se numete adres efectiv; fiind o adres pe 20 de bii poate accesa 220 octei de memorie, adic 1 MB de memorie. Construirea adresei efective este prezentat n figura 3.9.

Elemente de arhitectur a sistemelor de calcul i operare

- adresa de segment se deplaseaz la stnga cu 4 bii o cifr hexa - se adun adresa de deplasament - se obine adresa efectiv pe 20 de bii (5 cifre hexa)
Fig. 3.9 Exemplu de calcul al adresei efective

Registrul CS acest registru face referire la nceputul blocului de 64 KB de memorie n care se afl codul programului (segmentul de cod). Microprocesorul 8086 nu poate aduce alt instruciune pentru execuie dect cea definit de CS. Registrul CS poate fi modificat de un numr de instruciuni, precum instruciuni de salt, apel sau de ntoarcere. El nu poate fi ncrcat n mod direct cu o valoare, ci doar prin intermediul unui alt registru general. Registrul DS face referire ctre nceputul segmentului de date, unde se afl mulimea de date cu care lucreaz programul aflat n execuie. Registrul ES face referire la nceputul blocului de 64 KB cunoscut sun denumirea de extrasegment. Acesta nu este dedicat nici unui scop anume, fiind disponibil pentru diverse aciuni. Uneori acesta poate fi folosit pentru creearea unui bloc de memorie de 64 KB adiional pentru date. Acest extrasegment lucreaz foarte bine n cazul instruciunilor de tip STRING. Toate instruciunile de tip STRING ce scriu n memorie folosesc adresarea ES : DI ca adres de memorie. Registrul SS face referire la nceputul segmentului de stiv, care este blocul de 64 KB unde se afl stiva. Toate instruciunile ce folosesc implicit registrul SP (instruciunile POP, PUSH, CALL, RET) lucreaz n segmentul de stiv deoarece registrul SP este capabil s adreseze memoria doar n segmentul de stiv.

Introducere n limbajul de programare Intel

3.2 Elemente ale limbajului de asamblare 3.2.1 Formatul general al unei instruciuni n limbaj de asamblare O linie de cod scris n limbaj de asamblare are urmtorul format general: <nume> <instruciune/directiv> <operanzi> <;comentariu> unde: <nume> - reprezint un nume simbolic opional; <instruciune/directiv> - reprezint mnemonica (numele) unei instruciuni sau a unei directive; <operanzi> - reprezint o combinaie de unul, doi sau mai muli operanzi (sau chiar nici unul), care pot fi constante, referine de memorie, referine de regitri, iruri de caractere, n funcie de structura particular a instruciunii; <;comentariu> - reprezint un comentariu opional ce poate fi plasat dup caracterul ; pn la sfritul liniei respective de cod. 3.2.2 Nume de variabile i etichete Numele folosite ntr-un program scris n limbaj de asamblare pot identifica variabile numerice, variabile ir de caractere, locaii de memorie sau etichete. Spre exemplu, urmtoarea secven de cod, care calculeaz valoarea lui trei factorial (3! = 1 x 2 x 3 = 6) cuprinde cteva nume de variabile i etichete: .MODEL small .STACK 200h .DATA Valoare_Factorial DW ? Factorial DW ?

Elemente de arhitectur a sistemelor de calcul i operare

.CODE Trei_Factorial PROC MOV ax, @data MOV ds, ax MOV [Valoare_Factorial], 1 MOV [Factorial], 2 MOV cx, 2 Ciclare: MOV ax, [Valoare_Factorial] MUL [Factorial] MOV [Valoare_Factorial], ax INC [Factorial] LOOP Ciclare RET Trei_Factorial ENDP END Numele Valoare_Factorial i Factorial sunt utilizate pentru definirea a dou variabile de tip word (pe 16 bii), Trei_Factorial identific numele procedurii (subrutinei) ce conine codul pentru calculul factorialului, permind apelul su din alt parte a programului. Ciclare reprezint un nume de etichet, identificnd adresa instruciunii MOV ax, [Valoare_Factorial], astfel nct instruciunea LOOP folosit mai jos s poat face un salt napoi la aceast instruciune. Numele de variabile pot conine urmtoarele caractere: literele a-z i A-Z, cifrele de la 0-9 precum i caracterele speciale _ (underscore liniu de subliniere), @ (at n englez citit i a rond sau coad de maimu), $ i ?. Se poate folosi si caracterul punct (.) drept prim caracter al numelui unei etichete. Cifrele 0-9 nu pot fi utilizate pe prima poziie a numelui; de asemenea, nu pot fi folosite nume care s conin un singur caracter $ sau ?. Fiecare nume poate fi definit o singur dat (numele sunt unice) i pot fi utilizate ca operanzi de oricte ori se dorete ntr-un program. Un nume poate s apar ntr-un

Introducere n limbajul de programare Intel

program singur pe o linie (linia respectiv nu mai conine alt instruciune sau directiv). n acest caz, valoarea numelui este dat de adresa instruciunii sau directivei de pe linia urmtoare din program. De exemplu, n secvena urmtoare: ... JMP scdere ... scdere: SUB AX, CX ... urmtoarea instruciune care va fi executat dup instruciunea JMP scadere va fi instruciunea SUB AX, CX. Exemplul anterior este echivalent cu secvena: ... JMP scdere ... scdere: SUB AX, CX ... Exist unele avantaje atunci cnd scriem instruciunile pe linii separate. n primul rnd, atunci cnd scriem un nume de etichet pe o singur linie, este mai uor s folosim nume lungi de etichete fr a strica forma programului scris n limbaj de asamblare. n al doilea rnd, este mai uor s adugm ulterior o nou instruciune n dreptul etichetei dac aceasta nu este scris pe aceeai linie cu instruciunea. Numele variabilelor sau etichetelor folosite ntr-un program nu trebuie s se confunde cu numele rezervate de asamblor, cum ar fi numele de directive i instruciuni, numele regitrilor, etc. De exemplu, o declaraie de genul: ... ax DW 0 BYTE: ...

Elemente de arhitectur a sistemelor de calcul i operare

nu poate fi acceptat, deoarece AX este numele registrului acumulator, AX, iar BYTE reprezint un cuvnt cheie rezervat. Orice nume de etichet ce apare pe o linie fr instruciuni sau apare pe o linie cu instruciuni trebuie s aib semnul : dup numele ei. Tototdat, se ncearc s se dea un nume sugestiv etichetelor din program. Fie urmtorul exemplu: ... CMP AL, a JB Nu_este_liter_mic CMP AL, z JA Nu_este_liter_mic SUB AL, 20H Nu_este_liter_mic: comparativ cu: ... CMP AL, a JB x5 CMP AL, z JA x5 SUB AL, 20H x5: Dac n primul caz am folosit un nume sugestiv de etichet (Nu_este_liter_mic), n cazul al doilea, identic din punct de vedere al funcionalitii cu primul, eticheta a fost denumit x5, absolut nesugestiv! Observaie: Limbajul de asamblare nu este case sensitive. Aceasta semnific faptul c, ntr-un program scris n limbaj de asamblare, numele de variabile, etichete, instruciuni, directive, mnemonice etc., pot fi scrise att cu litere mari ct i cu litere mici, nefcndu-se diferena ntre ele (Nu _ este _ liter _ mic este acelai lucru cu nu_este_liter_mic sau Nu_Este_Liter_Mic etc.). ; se transform n liter mare ; se transforma in litera mare

Introducere n limbajul de programare Intel

3.2.3 Directive de segment simplificate Datorit faptului c regitrii microprocesorului 8086 sunt regitrii pe 16 bii, s-a impus folosirea unor segmente de memorie de cte 64 Ko (maxim ct se poate adresa avnd la dispoziie 16 bii 64 Ko = 2 ^ 16 = 65536). ntr-un program scris n limbaj de asamblare (vom folosi n continuare prescurtarea ASM) exist trei segmente: segmentul de cod, segmentul de date i segmentul de stiv. Directivele de segment (fie sub form standard, fie sub form simplificat) sunt necesare n orice program scris n limbaj de asamblare pentru a defini i controla utilizarea segmentelor iar directiva END este folosit ntotdeauna pentru a ncheia codul programului. Exemple de directive de segment simplificate sunt: .STACK .CODE .DATA .MODEL DOSSEG END .STACK,.CODE,.DATA definesc, respectiv, segmentele de stiv, de cod i de date. De exemplu, .STACK 200H definete o stiv de 512 octei (n ASM valorile ce sunt ncheiate cu litera H semnific faptul c este vorba despre hexazecimal). O astfel de valoare pentru stiv este suficient n mod normal; unele programe, ns (ndeosebi cele recursive) pot necesita dimensiuni mai mari ale stivei. Directiva .CODE marcheaz nceputul segmentului de cod. Directiva .DATA marcheaz nceputul segmentului de date, adic locul n care vom plasa variabilele de memorie. Reprezentativ aici este faptul c trebuie ncrcat n mod explicit registrul de segment DS cu valoarea "@data" naintea accesrii locaiilor de memorie n segmentul definit de .DATA. Avnd n vedere c un registru de segment poate fi ncrcat fie dintr-un registru general fie dintr-o locaie de memorie dar nu

Elemente de arhitectur a sistemelor de calcul i operare

poate fi ncrcat direct cu o constant, registrul de segment DS este ncrcat n general printr-o secven de dou instruciuni: ... mov ax, @data mov ds, ax ... (se poate folosi i alt registru general n locul lui AX). Secvena anterioar semnific faptul c DS se va referi ctre segmentul de date ce ncepe cu directiva .DATA. Considerm n continuare un exemplu de program ce afieaz textul memorat n DataString pe ecran: ;Program p01.asm .MODEL small .STACK 200H .DATA DataString DB 'Hello!$' ;se specific modelul de memorie ;SMALL ;se definete o stiv de 512 octei ;se specific nceputul segmentului de ;date ;se definete variabila ;DataString, iniializat cu valoarea ;"Hello!" .CODE ProgramStart: mov bx,@data ;nceputul segmentului de cod al ;programului ;orice program are o etichet de ;nceput ;secvena ce seteaz registrul DS s ;fac referire la segmentul de date ce ;ncepe cu .DATA

mov ds,bx mov dx, OFFSET DataString ;se ncarc n DX adresa ;variabilei DataString mov ah,09 ;codul funciei DOS de afiare a unui ;string

Introducere n limbajul de programare Intel

int 21H mov ah, 4cH

;apelul DOS de afiare a string-ului ;codul funciei DOS de terminare a ;programului ;apelul DOS de terminare ;a programului

int 21H

END ProgramStart

;directiva de terminare a codului ;programului

Explicaii: 1. Se pot introduce comentarii ntr-un program ASM prin folosirea ";". Tot ce urmeaz dup ";" i pn la sfritul liniei este considerat comentariu. 2. Nu are importan dac programul este scris folosind litere mari sau mici (nu este "case sensitive"). 3. Fr cele dou instruciuni care seteaz registrul DS ctre segmentul definit de .DATA, funcia de afiare a string-ului nu ar fi funcionat cum trebuie. Variabila DataString se afl n segmentul .DATA i nu poate fi accesat dac DS nu este poziionat ctre acest segment. Acest lucru se explic n modul urmtor: atunci cnd facem apelul DOS de afiare a unui string, trebuie s parcurgem ntreaga adres de tipul segment:offset a string-ului n DS:DX. De aceea, de abia dup ce am ncrcat DS cu segmentul .DATA i DX cu adresa (offset-ul) lui DataString avem o referin complet segment:offset ctre DataString.

Observaii: Nu trebuie s ncrcm n mod explicit registrul de segment CS deoarece DOS face acest lucru automat n momentul cnd rulm un program. Astfel, dac CS nu ar fi deja setat la momentul execuiei primei instruciuni din program, procesorul nu ar ti unde s gseasc instruciunea i programul nu ar rula niciodat. n mod asemntor, registrul de segment SS este setat de DOS nainte de execuia programului i de regul rmne nemodificat pe perioada execuiei programului.

Elemente de arhitectur a sistemelor de calcul i operare

Cu registrul de segment DS lucrurile stau altfel. n timp ce registrul CS se refer la intruciuni (cod), SS se refer ("pointeaz") la stiv, DS "pointeaz" la date. Programele nu manipuleaz direct instruciuni sau stive dar au de-a face n mod direct cu date. De asemenea, programele vor acces la date situate n segmente diferite n orice moment. Se poate dori ncrcarea n DS a unui segment, accesarea datelor din acel segment i apoi ncrcarea lui DS cu un alt segment pentru a accesa un bloc diferit de date. n programe mici sau medii nu vom avea nevoie de mai mult de un segment de date dar programe mai complexe folosesc deseori segmente de date multiple. Urmtorul program va afia un caracter pe ecran, folosind ncrcarea registrului ES n locul lui DS. ;Program p02.asm .MODEL small .STACK 200H .DATA OutputChar DB 'B' .CODE ProgramStart: mov dx, @data mov es, dx ;spre deosebire de programul anterior, ;se folosete ES pentru specificarea ;segmentului de date ;se ncarc BX cu adresa ;variabilei OutputChar mov dl, es:[bx] ;se ncarc AL cu valoarea de la ;adresa explicit es:[bx] ;(adresare indexat) mov ah,02 int 21H ;codul funciei DOS de afiare a unui caracter ;apelul DOS de execuie a afirii ;definirea variabilei OutputChar ;iniializat cu valoarea "B"

mov bx, offset OutputChar

Introducere n limbajul de programare Intel

mov ah, 4cH int 21H END ProgramStart

;codul funciei DOS de terminare a ;programului ;apelul DOS de terminare ;a programului ;directiva de terminare a codului ;programului

DOSSEG este directiva ce face ca segmentele dintr-un program s fie grupate conform conveniilor Microsoft de adresare a segmentelor. Directiva .MODEL Este directiva ce specific modelul de memorie pentru un program ASM ce folosete directive de segment simplificate. Definiii: "near" nseamn adresa (offset-ul) pe 16 bii din cadrul aceluiai segment, n timp ce "far" nseamn o adres complet de tip segment:offset, din cadrul altui segment dect cel curent. Modelele de memorie ce se pot specifica prin intermediul directivei .MODEL sunt: - tiny - att codul ct i datele programului ncap n acelai segment de 64 Ko. Att codul ct i datele sunt de tip near. - small - codul programului trebuie s fie ntr-un singur segment de 64 Ko i datele ntr-un bloc separat de 64Ko; codul i datele sunt near - medium - codul programului poate fi mai mare dect 64 Ko dar datele trebuie s fie ntr-un singur segment de 64 Ko. Codul este far, datele sunt near. - compact - codul programului poate fi ntr-un singur segment, datele pot fi mai mari de 64 Ko. Codul este near, datele sunt far. - large - att codul ct i datele pot depi 64Ko, dar nici un masiv de date nu poate depi 64 Ko. Att codul ct i datele sunt far. - huge - att codul ct i datele pot depi 64 Ko i masivele de date pot depi 64 Ko. Att codul ct i datele sunt far. Pointerii la elementele dintr-un masiv sunt far.

Elemente de arhitectur a sistemelor de calcul i operare

n continuare sunt prezentate cteva exemple legate de modalitile de declarare a variabilelor i de adresare a memoriei: var1 DW 01234h var2 DW 01234 var3 RESW 1 var4 DW ABCDh ;se definete o variabil word cu ;valoarea 1234h ;se definete o variabil word cu ;valoarea zecimal 1234 (4D2 in hexa) ;se rezerv spaiu pentru o variabil ;word (de valoare 0) ;atribuire ilegal!

mesajsco2 DB 'SCO 2 este cursul preferat!' ...start: mov ax,cs mov ds,ax ; setarea segmentului de date ; DS=CS

; orice referin de memorie se presupune c este relativ la segmentul DS mov ax,[var2] ; AX <- var2 ; == mov ax,[2] mov si,var2 ;se folosete SI ca pointer ctre var2 ;(cod C echivalent SI=&var2) ;se citete din memorie valoarea lui ;var2 (*(&myvar2)) ;(referin indirect) mov bx,mesajsco2 ; BX este pointer la un string ; (cod C echivalent: BX=&mesajsco2)

mov ax,[si]

Introducere n limbajul de programare Intel

dec BYTE [bx+1] mov si, 1 inc byte [mesajsco2+SI]

; transform 'C' in 'B' ! ; Folosete SI cu rol de index ; == inc byte [SI + 8] ; == inc byte [9]

; Memoria poate fi adresata folosindu-se patru regitri: ; SI -> Implic DS ; DI -> Implic DS ; BX -> Implic DS ; BP -> Implic SS ! (nu este foarte des utilizat) ; Exemple: mov ax,[bx] mov al,[bx] mov ax,[si] mov ah,[si] mov cx,[di] mov ax,[bp] ; ax <- word n memorie referit de BX ; al <- byte n memorie referit de BX ; ax <- word referit de SI ; ah <- byte referit de SI ; di <- word referit de DI ; AX <- [SS:BP] Operaie cu stiva!

; n plus, sunt permise BX+SI i BX+DI: mov ax,[bx+si] mov ch,[bx+di]

Elemente de arhitectur a sistemelor de calcul i operare

; Deplasamente pe 8 sau 16 biti: mov ax,[23h] mov ah,[bx+5] mov ax,[bx+di+47] ; ax <- word n memorie DS:0023 ; ah <- byte n memorie [DS:BX+5] ; ax <- word la adresa [DS:BX+DI+47]

mov ax,[bx+si+107] ; ax <- word la adresa [DS:BX+SI+107]

; ATENIE: copierea din memorie n memorie este ilegal! ;Totdeauna trebuie s se treac valoarea copiat printr-un registru mov [bx],[si] ;Ilegal mov [di],[si] ;Ilegal ; Caz special: operaiile cu stiva! pop word [var] ; var <- [SS:SP]

3.2.4 Adrese de memorie i valori Un program scris n limbaj de asamblare se poate referi fie la o adres de memorie (OFFSET = DEPLASAMENT), fie la o valoare stocat de variabil n memorie. Din pcate, limbajul de asamblare nu este nici strict, nici intuitiv cu privire la modurile n care aceste dou tipuri de referire sunt fcute i, drept urmare, referirile la OFFSET sau la valoare sunt deseori confundate. n figura 3.10 sunt ilustrate conceptele de adres de deplasament (offset) i valoare stocat n memorie.

Introducere n limbajul de programare Intel

Fig. 3.10 Ilustrarea noiunilor de adres de deplasament i valoare stocat n memorie

Deplasamentul unei variabile de memorie var de dimensiune word este valoarea constant 5004H, obinut cu operatorul OFFSET. Spre exemplu, instruciunea: MOV BX, OFFSET var ncarc valoarea 5004H n registrul BX. Valoarea 5004H nu se modific; ea este construit n cadrul instruciunii. Valoarea lui var este 1234H, citit din memorie la adresa dat de offset-ul 5004H din segmentul de date. O modalitatea de citire a acestei valori este de a ncrca registrele BX, SI, DI sau BP cu offset-ul lui var i apoi folosirea registrului respectiv pentru adresarea memoriei. Instruciunile: MOV BX, OFFSET var MOV AX, [ BX ] au ca efect ncrcarea valorii lui var (1234H) n registrul AX.

Elemente de arhitectur a sistemelor de calcul i operare

De asemenea, se poate ncrca valoarea lui var direct n AX folosind: MOV AX, var Sau MOV AX, [ var ] n timp ce valoarea deplasamentului rmne constant, valoarea 1234H nu este permanent asociat cu var. De exemplu, instruciunile: MOV [ var ], 5555H MOV AX, [ var ] au ca efect ncrcarea valorii 5555H n registrul AX. Cu alte cuvinte, n timp ce deplasamentul lui var este o valoare constant ce descrie o adres fix dintr-un segment de date, valoarea variabilei var este un numr ce poate fi modificat i care se afl memorat la adresa (de memorie) respectiv. Instruciunile: MOV [ var ], 1 ADD [ var ], 2 modific valoarea lui var la 3, dar instruciunea: ADD OFFSET var, 2 este echivalent cu ADD 5002H, 2, ceea ce este un lucru fr sens, deoarece este imposibil s se nsumeze o constant cu alta. O problem ce poate aprea adesea n timpul programrii este aceea a omiterii lui OFFSET; de exemplu, dac scriem MOV SI, var atunci cnd, de fapt, dorim ncrcarea n SI a deplasamentului lui var. Nu va fi semnalat nici o eroare n acest caz, avnd n vedere c var este o variabil de tip word. Totui, n momentul execuiei programului, registrul SI va fi ncrcat cu valoarea lui var (1234H), n loc de OFFSET, ceea ce poate conduce la rezultate imprevizibile. n acest caz, referirile la constantele de adres vor fi precedate de OFFSET iar referirile la valori din memorie s fie cuprinse ntre paranteze drepte ([ i ]), eliminnd astfel ambiguitatea.

Introducere n limbajul de programare Intel

3.2.5 Instruciuni ale microprocesorului Intel Microprocesoarele din familia Intel x86 dispun de o serie impresionant de instruciuni, asemeni tuturor procesoarelor din clasa procesoarelor CISC (Complex Instruction Set Computer). Instruciunile se pot mpri n: instruciuni logice, aritmetice, de transfer i de control. Prezentm n continuare cteva exemple din fiecare clas de instruciuni. 3.2.5.1 Instruciuni logice Instruciunile logice implementeaz funciile logice de baz, pe un octet sau pe cuvnt. Ele acioneaz bit cu bit, deci se aplic funcia logic respectiv tuturor biilor sau perechilor de bii corespunztori operanzilor. Instruciunile logice sunt urmtoarele: NOT: A =~A AND: A &= B OR: A |= B XOR: A ^= B TEST: A & B De regul, instruciunile logice au efect asupra indicatorilor de stare, cu excepia instruciunii NOT, care nu are efect asupra nici unui flag (indicator de stare). Aceste efecte sunt urmtoarele: Se terge indicatorul carry (C) Se terge indicatorul overflow (O) Se seteaz zero flag (Z) dac rezultatul este zero, sau l terge n caz contrar Se copiaz bitul mai nalt al rezultatului n indicatorul sign (S) Se seteaz bitul de paritate (P) conform cu paritatea rezultatului

Elemente de arhitectur a sistemelor de calcul i operare

Instruciunea NOT Este o instruciune cu un singur operand (instruciune unar), cu forma general: NOT destinatie Unde destinaie este fie un registru, fie o locaie de memorie pe 8 sau 16 bii. Instruciunea are ca efect inversarea (negarea) tuturor biilor operandului, adic aducerea n forma codului invers - complement fa de 1. Instruciunea AND Este o instruciune cu doi operanzi (instruciune binar), cu forma general: AND destinaie, sursa Unde destinatie este fie un registru, fie o locaie de memorie pe 8 sau 16 bii, iar sursa poate fi registru, locaie de memorie sau o constant pe 8 sau 16 bii. Instruciunea are ca efect operaia: <destinaie> == <destinaie> AND <surs>. Indicatorii de stare modificai sunt: SF, ZF, PF, CF, OF = 0, AF nedefinit. Instruciunea TEST (AND non-distructiv) Este o instruciune cu doi operanzi (instruciune binar), cu forma general: TEST destinaie, sursa Unde destinatie este fie un registru, fie o locaie de memorie pe 8 sau 16 bii, iar sursa poate fi registru, locaie de memorie sau o constant pe 8 sau 16 bii. Instruciunea are acelai efect ca i instruciunea AND, cu deosebirea c nu se modific operandul destinaie, iar indicatorii de stare sunt modificai n acelai mod ca i n cazul instruciunii AND. Instruciunea OR Este o instruciune cu doi operanzi, cu forma general: OR destinaie, sursa Unde destinaie este fie un registru, fie o locaie de memorie pe 8 sau 16 bii, iar sursa poate fi registru, locaie de memorie sau o constant pe 8 sau 16 bii. Instruciunea are efectul: <destinaie> == <destinaie> OR <surs>. Indicatorii de stare modificai sunt: SF, ZF, PF, CF, OF = 0, AF nedefinit.

Introducere n limbajul de programare Intel

Instruciunea XOR (SAU-Exclusiv) Este o instruciune cu doi operanzi, cu forma general: XOR destinaie, sursa Unde destinaie este fie un registru, fie o locaie de memorie pe 8 sau 16 bii, iar sursa poate fi registru, locaie de memorie sau o constant pe 8 sau 16 bii. Instruciunea are efectul: <destinaie> == <destinaie> XOR <surs>. Indicatorii de stare modificai sunt: SF, ZF, PF, CF, OF = 0, AF nedefinit. Funcia XOR, denumit SAU-Exclusiv (sau anticoinciden) are valoarea logic 1 atunci cnd operanzii si sunt diferii (unul are valoarea 0 iar cellalt valoarea 1) i valoarea logic 0 cnd ambii operanzi au aceeai valoare (fie ambii au valoarea 0, fie ambii au valoarea 1). Observaie: De cele mai multe ori, instruciunile AND i OR sunt folosite pe post de mascare a datelor; n acest sens, o valoarea de tip masc (mask) este utilizat pentru a fora anumii bii s ia valoarea zero sau valoarea 1 n cadrul altei valori. O astfel de masc logic are efect asupra anumitor bii, n timp ce pe alii i las neschimbai. Exemple: Instruciunea AND CL, 0Fh face ca cei mai semnificativi 4 bii s ia valoarea 0, n timp ce biii mai puin semnificativi sunt lsai neschimbai; astfel, dac registrul CL are valoarea iniial 1001 1101, dup execuia instruciunii AND CL, 0Fh va avea valoarea 0000 1101. Instruciunea OR CL, 0Fh face ca cei mai puin semnificativi 4 bii s ia valoarea 1, n timp ce biii mai semnificativi s rmn nemodificai. Dac registrul CL are valoarea iniial 1001 1101, dup execuia instruciunii OR CL, 0Fh va avea valoarea 1001 1111.

Elemente de arhitectur a sistemelor de calcul i operare

Fig. 3.11 Instruciuni de deplasare i de rotaie

3.2.5.2 Instruciuni de deplasare i de rotaie Acest tip de instruciuni (vezi figura 3.11) permit realizarea operaiilor de deplasare i de rotaie la nivel de bit. Ele au doi operanzi, primul operand fiind cel asupra cruia se aplic operaia de deplasare pe bii, iar cele de-al doilea (operandul numrtor sau contor) semnific numrul de bii cu care se face aceast deplasare. Operaiile se pot face de la dreapta spre stnga sau invers. Deplasarea nseamn translatarea tuturor biilor din operand la stnga/dreapta, cu completarea unei valori fixe n poziia rmas liber i cu pierderea biilor din dreapta/stnga. Rotaia presupune translatarea biilor din operand la stnga/dreapta, cu completarea n dreapta/stnga cu biii care se pierd n partea opus. Sintaxa general a instruciunilor de deplasare i rotaie este urmtoarea: INSTR <operand> , <contor>

Introducere n limbajul de programare Intel

Unde INSTR reprezint numele instruciunii, <operand> reprezint un registru sau o locaie de memorie pe 8 sau 16 bii, iar <contor> semnific numrul de bii cu care se face deplasarea, adic fie o constant, fie registrul CL (care i confirm astfel rolul de numrtor). Observaie Totdeauna exist dou modaliti de deplasare: Prin folosirea unui contor efectiv de exemplu: SHL AX, 1 Prin folosirea registrului CL pe post de contor de exemplu: SHL AX, CL Instruciunea SHL/SAL (Shift Left/Shift Arithmetic Left) Aceast instruciune translateaz biii operandului o poziie la stnga de cte ori specific operandul numrtor. Poziiile rmase libere prin deplasarea la stnga sunt umplute cu zerouri la bitul cel mai puin semnificativ, n timp ce bitul cel mai semnificativ se deplaseaz n indicatorul CF (Carry Flag). Reprezint o modalitate rapid de nmulire cu o putere a lui 2 (n funcie de numrul de bii pentru care se face deplasarea la stnga). Exemple: 1. nmulirea lui AX cu 10 (1010 n binar) (nmulim cu 2 i cu 8, apoi adunm rezultatele) SHL SHL ax, 1 ax, 2 ; AX ori 2 ; salvm 2*AX n BX ; 2*AX(original) * 4 = 8*AX(original) ; 2*AX + 8*AX = 10*AX MOV bx, ax ADD ax, bx

2. nmulirea lui AX cu 18 (10010 n binar) (nmulim cu 2 i cu 16, apoi adunm rezultatele) SHL SHL ax, 1 ax, 3 ; AX ori 2 ; salvm 2*AX ; 2*AX(original) ori 8 = 16*AX(original) ; 2*AX + 16*AX = 18*AX MOV bx, ax ADD ax, bx

Elemente de arhitectur a sistemelor de calcul i operare

Instruciunea SHR (Shift Right) Aceast instruciune translateaz biii operandului o poziie la dreapta de cte ori specific operandul numrtor. Bitul cel mai puin semnificativ se deplaseaz n indicatorul CF (Carry Flag). Reprezint o modalitate rapid de mprire fr semn la o putere a lui 2 (dac deplasarea se face cu o poziie la dreapta, operaia este echivalent cu o mprire la 2, dac deplasarea se face cu dou poziii, operaia este echivalent cu o mprire la 22, etc.). Operaia de mprire se execut fr semn, completndu-se cu un bit 0 dinspre stnga (bitul cel mai semnificativ). Instruciunea SAR (Shift Arithmetic Right) Aceast instruciune translateaz biii operandului o poziie la dreapta de cte ori specific operandul numrtor. Bitul cel mai semnificativ rmne neschimbat, n timp ce bitul cel mai puin semnificativ este copiat n indicatorul CF (Carry Flag). Reprezint o modalitate rapid de mprire cu semn la o puterea a lui 2 (n funcie de numrul de bii cu care se face deplasarea la dreapta). Instruciunea RCL (Rotate through Carry Left) Aceast instruciune determin o rotaie a biilor operandului ctre stnga prin intermediul lui CF (Carry Flag). Astfel, cel mai semnificativ bit trece din operand n CF, apoi se deplaseaz toi biii din operand cu o poziie la stnga iar CF original trece n bitul cel mai puin semnificativ din operand. Instruciunea ROL (Rotate Left) Aceast instruciune determin o rotaie a biilor operandului ctre stnga. Astfel, cel mai semnificativ bit trece din operand n bitul cel mai puin semnificativ.

Introducere n limbajul de programare Intel

Exemplu. Dup execuia instruciunilor: ROL AX, 6 AND AX, 1Fh Biii 10-14 din AX se mut n biii 0-4. Instruciunea RCR (Rotate through Carry Right) Aceast instruciune determin o rotaie a biilor operandului ctre dreapta prin intermediul lui CF (Carry Flag). Astfel, bitul din CF este scris napoi n bitul cel mai semnificativ al operandului. Instruciunea ROR (Rotate Right) Aceast instruciune determin o rotaie a biilor operandului ctre dreapta. Bitul cel mai puin semnificativ trece n bitul cel mai semnificativ. Exemple: MOV ax,3 ; Valori iniiale AX = 0000 0000 0000 0011 MOV bx,5 ; BX = 0000 0000 0000 0101 OR ax,9 ; ax <- ax | 0000 1001 AX = 0000 0000 0000 1011 AND ax,10101010b ; ax <-ax&1010 1010 AX = 0000 0000 0000 1010 XOR ax,0FFh ; ax <- ax ^ 1111 1111 AX = 0000 0000 1111 0101 NEG ax ; ax <- (-ax) AX = 1111 1111 0000 1011 NOT ax ; ax <- (~ax) AX = 0000 0000 1111 0100 OR ax,1 ; ax <- ax | 0000 0001 AX = 0000 0000 1111 0101 SHL ax,1 ; depl logic la stg cu 1 bit AX = 0000 0001 1110 1010 SHR ax,1 ; depl logic la dr cu 1 bit AX = 0000 0000 1111 0101 ROR ax,1 ; rotaie stg (LSB=MSB) AX = 1000 0000 0111 1010 ROL ax,1 ; rotaie dr (MSB=LSB) AX = 0000 0000 1111 0101 MOV cl,3 ; folosim CL pt depl cu 3 bii CL = 0000 0011 SHR ax,cl ; mprim AX la 8 AX = 0000 0000 0001 1110 MOV cl,3 ; folosim CL pt depl cu 3 bii CL = 0000 0011 SHL bx,cl ; nmulim BX cu 8 BX = 0000 0000 0010 1000

Elemente de arhitectur a sistemelor de calcul i operare

3.2.5.3 Instruciuni aritmetice Instruciunea ADD (ADDition) Instruciunea ADD are formatul general: ADD <destinaie> <surs> Unde <destinaie> poate fi un registru general sau o locaie de memorie, iar <surs> poate fi registru general, locaie de memorie sau o valoare imediat. Cei doi operanzi nu pot fi ns n acelai timp locaii de memorie. Rezultatul operaiei este urmtorul: <destinaie> == <destinaie> + <surs>. Indicatorii de stare modificai n urma acestei operaii sunt: AF, CF, PF, SF, ZF, OF. Operanzii pot fi pe 8 sau pe 16 bii i trebuie s aib aceeai dimensiune. Dac apare ambiguitate la modul de exprimare al operanzilor (8 sau 16 bii) se va folosi operatorul PTR. Exemple: ADD AX, BX ADD DL, 33h MOV DI, NUMB MOV AL, 0 ADD AL, [DI] ADD AL, [DI + 1] ADD byte ptr VAR, 5 ; adunare ntre regitri AX ; adunare efectiv - DL ; adresa lui NUMB ; se terge suma ; adun [NUMB] ; adun [NUMB + 1] ; destinaie n memorie, surs imediat ; forarea instruciunii pe un octet, ;VAR fiind declarat DW AX + BX DL + 33h

ADD word ptr [DI], -2

Instruciunea INC (Increment addition) Instruciunea INC are formatul general: INC <destinaie> Unde <destinaie> este un registru sau un operand n memorie, pe 8 sau pe 16 bii iar semnificaia operaiei este incrementarea valorii destinaie cu 1. Toi indicatorii de stare sunt afectai, cu excepia lui CF (Carry Flag).

Introducere n limbajul de programare Intel

Exemplu: MOV DI, NUMB MOV AL, 0 ADD AL, [DI] INC DI ADD AL, [DI] ; adresa lui NUMB ; terge suma ; adun [NUMB] ; DI = DI + 1 ; adun [NUMB + 1]

Instruciunea ADC (ADdition with Carry) Instruciunea ADD are formatul general: ADD <destinaie> <surs> Unde <destinaie> poate fi un registru general sau o locaie de memorie, iar <surs> poate fi registru general, locaie de memorie sau o valoare imediat. Instruciunea acioneaz ntocmai ca ADD, cu deosebirea c la rezultat este adugat i bitul CF. Este utilizat, de regul, pentru a aduna numere mai mari de 16 bii (8086-80286) sau mai mari de 32 de bii la 80386, 80486, Pentium. Exemplu: Adunarea a dou numere pe 32 de bii se poate face astfel (BXAX) + (DXCX): ADD AX, CX ADC BX, DX Instruciunea SUB (SUBstract) Instruciunea SUB are formatul general: SUB <destinaie> <surs> Unde <destinaie> poate fi un registru general sau o locaie de memorie, iar <surs> poate fi registru general, locaie de memorie sau o valoare imediat. Rezultatul operaiei este urmtorul: <destinaie> == <destinaie> - <surs>. Indicatorii de stare modificai n urma acestei operaii sunt: AF, CF, PF, SF, ZF, OF. Operanzii pot fi pe 8 sau pe 16 bii i trebuie s aib aceeai dimensiune. Scderea poate fi vzut ca o adunare cu reprezentarea n complementul fa de 2 al operandului surs i cu

Elemente de arhitectur a sistemelor de calcul i operare

inversarea bitului CF, n sensul c, dac la operaie (adunarea echivalent) apare transport, CF=0 i dac la adunarea echivalent nu apare transport, CF=1. Pentru instruciunile: MOV CH, 22h SUB CH, 34h Rezultatul este -12 (1110 1110), iar indicatorii de stare se modific astfel: ZF = 0 (rezultat diferit de zero) CF = 1 (mprumut) SF = 1 (rezultat negativ) PF = 0 (paritate par) OF = 0 (fr depire) Instruciunea DEC (DECrement substraction) Instruciunea DEC are formatul general: DEC <destinaie> Unde <destinaie> este un registru sau un operand n memorie, pe 8 sau pe 16 bii iar semnificaia operaiei este decrementarea valorii destinaie cu 1. Toi indicatorii de stare sunt afectai, cu excepia lui CF (Carry Flag). Instruciunea SBB (SuBstract with Borrow) Instruciunea SBB are formatul general: SBB <destinaie>, <surs> Unde <destinaie> i <surs> pot fi registru sau operand n memorie, pe 8 sau pe 16 bii. Rezultatul operaiei este urmtorul: <destinaie> == <destinaie> - <surs> - CF, deci la fel ca i n cazul instruciunii SUB, dar din rezultat se scade i bitul CF. Indicatorii de stare modificai n urma acestei operaii sunt: AF, CF, PF, SF, ZF, OF. Aceast instruciune este utilizat, de regul, pentru a scdea numere mai mari de 16 bii (la 8086 - 80286) sau de 32 de bii (la 80386, 80486, Pentium).

Introducere n limbajul de programare Intel

Exemplu Scderea a dou numere pe 32 de bii se poate face astfel (BXAX) (SIDI): SUB SBB AX, DI BX, SI

Setarea indicatorilor de stare n cazul situaiilor de depire sau/i transport Indicatorul CF (Carry Flag) indic apariia unui transport n urma unei adunri sau un mprumut n cazul unei scderi. n cazul unei operaii fr semn, CF este setat (ia valoarea 1) atunci cnd apare transport i nu este setat (are valoarea 0) dac nu apare transport. De exemplu, dac adunm valorile 36864 (9000h) + 36864 (9000h) = 73728 (12000h) > 65535 (FFFFh), rezultatul depete valoarea maxim 65535, deci CF va avea valoarea 1. n concluzie, bitul carry este setat atunci cnd numrul fr semn iese din domeniu (nseamn c operaia aritmetic a generat depire). De asemenea, poate s apar situaia de depire (indicatorul OF Overflow Flag este setat) atunci cnd se adun sau se scad numere fr semn. De exemplu, pentru adunarea 20480 (5000h) + 20480 (5000h) = 40960 (A000h) > 32767 (7FFFh) indicatorul OF este setat, iar CF nu este setat (avem depire, fr transport). Indicatorul OF este setat atunci cnd numrul cu semn depete domeniul de definiie. De exemplu, n cazul FFFFh + FFFFh = FFFEh = (-1) + (-1) = -2, rezultatul operaiei este fr depire, cu transport. n figura 3.12 putem vedea cum se realizeaz setarea indicatorilor de stare.

Elemente de arhitectur a sistemelor de calcul i operare

Alte exemple:
MOV ADD ax, 0fffeh ; 65534 interpretat ca fr semn ax, 3 ; C = 1, O = 0 --- Condiie de overflow ; fr semn ax, 0FFFEh ax, 3 bx, 07FFFh bx, 1 ; -2 interpretat ca numr cu semn ; C = 1, O = 0 --- Ok - nr cu semn ; 32767 interpretat ca nr cu semn ; C = 0, O = 1 --- Condiie de Overflow ; cu semn ; 32767 interpretat ca fr semn ; C = 0, O = 1 --- Ok - fr semn

MOV ADD MOV ADD

MOV ADD MOV ADD

bx, 07FFFh bx, 1

ax, 07h ; 7 interpretat fie cu semn fie fr semn ax, 03h ; C = 0, O = 0 --- Ok indiferent de semn

3.2.5.4 Instruciuni de salt Instruciunea de salt necondiionat JMP Aceast instruciune are sintaxa general: JMP etichetaUnde eticheta indic adresa (locul) unde se face saltul, de regul prin specificarea unei etichete ce indic un nume de procedur, o etichet definit cu : sau o etichet definit cu directiva LABEL. Exemple de etichete: eticheta1: contor: eticheta2 LABEL FAR stop LABEL NEAR

Introducere n limbajul de programare Intel

Din punct de vedere al saltului exist trei tipuri de instruciuni JMP: Short jump - instruciune pe 2 octei ce permite saltul la locaia de memorie n intervalul +127 i -128 octei de la locaia de memorie ce urmeaz saltului are forma: JMP SHORT eticheta Near jump - instruciune pe 3 octei ce permite saltul la locaia de memorie n intervalul +/-32KB de la locaia de instruciunii din segmentul de cod curent are forma: JMP eticheta Far jump - instruciune pe 5 octei ce permite saltul la o locaie de memorie n ntreg spaiul de memorie are forma: JMP etichetaPentru microprocesoarele 80386 i 80486 saltul de tip near este n spaiul de memorie +/-2G dac computerul opereaz n mod protejat i n domeniul +/-32K bytes pentru modul real. Instruciuni de salt condiional Dup cum am vzut mai nainte, instruciunile aritmetice i logice determin modificarea indicatorilor de stare; cu alte cuvinte, aceti indicatori ne ofer permanent informaii cu privire la rezultatele instruciunilor anterioare. Prin utilizarea valorilor indicatorilor de stare se pot realiza aa numitele salturi condiionale, n care se realizeaz transferul execuiei ctre o alt instruciune din cadrul programului. Dac o condiie de testare a fost adevrat atunci se face un salt nainte sau napoi ctre locaia specificat (pointerul de instruciune IP ne indic n fiecare moment adresa urmtoarei instruciuni ce va fi executate). Dac acea condiie de testare a fost fals, se continu execuia programului cu urmtoarea instruciune (IP este incrementat ca de obicei). Salturile condiionale sunt ntotdeauna de tip short pentru 8086-80286; domeniul saltului este ntre 127 octei i -128 octei de la locaia urmtoare saltului condiional. De la 80386, salturile condiionale sunt fie short, fie near. Instruciunile de salt condiional testeaz urmtorii indicatori de stare: SF (Sign Flag), ZF(Zero Flag), CF(Carry Flag), PF (Parity Flag) i OF (Overflow Flag).

Elemente de arhitectur a sistemelor de calcul i operare

Fig. 3.12 Setarea indicatorilor de stare

Observaie: Atenie la compararea valorii FFh cu valoarea 00h! n mulimea numerelor fr semn prima valoare este mai mare, pe cnd n mulimea numerelor cu semn prima valoare este mai mic (are valoarea -1). nainte de a prezenta instruciunile de salt condiional vom prezenta ns o instruciune care este folosit deseori n compania unei instruciuni de salt condiional: instruciunea CMP. Instruciunea CMP (CoMParison) Aceast instruciune compar dou valori X i Y, fiind echivalent cu o scdere care modific doar indicatorii de stare. Sintaxa general este: CMP destinaie surs Semnificaia este execuia unei scderi temporare destinaie surs, cu modificarea indicatorilor de stare. n cazul acestei instruciuni toi indicatorii de stare sunt afectai, fiind folosit pentru verificarea coninutului unui registru sau a unei locaii de memorie cu o alt valoare. De regul, aceast instruciune se folosete mpreun cu o instruciune de salt condiional. n figura 3.13 sunt prezentate modificrile indicatorilor de stare rezultate n urma instruciunii CMP. Exemplu: CMP al, 10h ; compar coninutul registrului AL cu 10h

Introducere n limbajul de programare Intel

JAE SUPER ; dac AL are valoarea 10h sau mai mult se face salt la ; locatia de memorie SUPER

Fig. 3.13 Setarea indicatorilor de stare n urma execuiei instruciunii CMP

Compararea ntregilor cu semn cu ajutorul instruciunii CMP se face astfel (considerm instruciunea CMP AX, BX): Indicatorul SF va fi setat n funcie de rezultatul AX-BX (dac are valoarea 1 n bitul cel mai semnificativ al rezultatului). Indicatorul OF va fi setat dac rezultatul AX-BX a produs un numr n afara domeniului de definiie (de exemplu -32768 +32767 pentru o reprezentare pe16 bii) reprezentat ca ntreg. Pentru instruciunile de salt condiional exist mai multe mnemonice pentru aceeai instruciune i dac condiia nu este ndeplinit, saltul nu are loc i se continu cu execuia instruciunii urmtoare din program. n figurile 3.14 i 3.15 sunt prezentate instruciunile de salt condiionat.

Elemente de arhitectur a sistemelor de calcul i operare

Fig. 3.14 Instruciuni de salt condiionat

O alt instruciune de salt este instruciunea LOOP, cu formatul general: LOOP eticheta unde eticheta este o locaie de memorie n program. Instruciunea LOOP reprezint o combinaie de decrementare a registrului general CX cu un salt condiional; mai precis, n prima faz LOOP decrementeaz CX (sau ECX pentru modul de lucru pe 32 de bii), iar dac CX este diferit de 0 se face salt la adresa indicat de eticheta. n cazul n care registrul CX este 0, se va executa urmtoarea instruciune din program (se continu execuia n mod normal, secvenial).

Introducere n limbajul de programare Intel

Fig. 3.15 Instruciuni de salt condiionat

3.3 Exemple de programe 1. Program care citete un numr de la tastatur i afieaz dac numrul este par sau nu. ; Programul citete un numr i afieaz un mesaj referitor la paritate dosseg .model small .stack .data mesaj db 13,10,'Introducei numrul:(<=9)$' mesg_par db 13,10,'Numrul introdus este par!$' mesg_impar db 13,10,'Numrul introdus este impar!$' .code pstart: mov ax,@data mov ds,ax mov ah,09 mov dx,offset mesaj int 21h

Elemente de arhitectur a sistemelor de calcul i operare

mov ah,01h ; se citete un caracter de la tastatur ; codul ASCII al caracterului introdus va fi n AL int 21h mov bx,2 div bx ; se mparte AX la BX, ctul va fi n AX, restul n DX cmp dx,0 jnz impar mov ah,09 mov dx,offset mesg_par int 21h jmp sfrit impar: mov ah,09 mov dx,offset mesg_impar int 21h sfarsit: mov ah,4ch int 21h ; sfritul programului END pstart 2. Program care calculeaz ptratul unui numr introdus de la tastatur. ; Programul calculeaz ptratul unui numr (<=256) introdus de la tastatur ; Valoarea ptratului se calculeaz n registrul AX (valoare maxim 2^16 = 65536) dosseg .model small .stack .data nr DB 10,10 dup(0) r DB 10, 10 dup(0) mesaj db 13,10,'Introducei numrul:(<=256)$' ptrat db 13,10,'Ptratul numrului este:$' .code pstart: mov ax,@data

Introducere n limbajul de programare Intel

mov ds,ax mov ah,09 mov dx,offset mesaj int 21h mov ah,0ah mov dx,offset nr int 21h mov cl,nr[1] introdus inc cl mov si,1 xor ax,ax mov bl,10 n BL nmultire: mul bl inc si mov dl,nr[si] sub dl,30h add ax,dx cmp si,cx jne nmulire mul ax xor si,si mov bx,10 cifra: ; aici ncepe afiarea rezultatului din AX div bx add dl,30h mov r[si],dl inc si xor dx,dx cmp ax,0 jne cifra mov ah,9 mov dx, offset ptrat ; n ir se va merge pn la poziia cl+1 ; folosesc registrul SI pe post de contor ; iniializez AX cu valoarea 0 ; se va nmuli cu valoarea 10 care este stocat ; ncarc n CL numrul de cifre al numrului

Elemente de arhitectur a sistemelor de calcul i operare

int 21h caracter: dec si mov ah,02 caracter mov dl,r[si] int 21h cmp si,0 jne caracter jmp sfrit

;apelarea funciei 02 pentru afiarea unui ;al carui cod ASCII este n DL

mov ah,9 mov dx,offset ptrat int 21h sfrit: mov ah,4ch int 21h ; stop program END pstart 3. Program care calculeaz valoarea unui numr ridicat la o putere. Att numrul ct i exponentul (puterea) sunt introduse de la tastatur. ; Programul calculeaz un numr ridicat la o putere ; Observaie. Deoarece rezultatul se calculeaz n registrul AX care ;este un registru pe 16 bii, valoarea maxim calculat corect este 2^16= ;65536 .model small .stack .data mesaj1 db 13,10,'Introducei numrul:(<=9)$' mesaj2 db 13,10,'Introducei puterea:(<=9)$' mesaj_final db 13,10,'Rezultatul este: $' mesaj_putere_0 db 13,10, 'Orice numr ridicat la puterea 0 este 1! $' r db 30 dup(0) ; n variabila r se va stoca rezultatul .code pstart: mov ax,@data mov ds,ax

Introducere n limbajul de programare Intel

mov ah,09 mov dx,offset mesaj1 int 21h mov ah,01h ; se citete un caracter de la tastatur ; codul ASCII al caracterului introdus va fi n AL int 21h and ax,00FFh sub ax, 30h ; se obine valoarea numeric ; sczndu-se codul lui 0 n ASCII (30H) push ax ; se salveaz valoarea lui ax n stiv mov ah,09 mov dx,offset mesaj2 int 21h mov ah,01h ; se citete un caracter de la tastatur ; codul ASCII al caracterului introdus va fi n AL int 21h and ax,00FFh sub ax, 30h ; se obine valoarea numeric ; sczndu-se codul lui 0 n ASCII (30H) mov cx,ax ;registrul CX contorizeaz numrul de nmuliri cmp cx,0 jne putere_0 mov ah,09 mov dx, offset mesaj_putere_0 int 21h jmp sfrit putere_0: pop bx ;se salveaz n BX valoarea cu care nmulete mov ax,0001 nmulire: mul bx loop nmulire xor si,si mov bx,10 cifra: div bx add dl,30h mov r[si],dl inc si xor dx,dx cmp ax,0

Elemente de arhitectur a sistemelor de calcul i operare

jne cifra mov ah,9 mov dx, offset mesaj_final int 21h caracter: dec si mov ah,02 ;apelarea funciei 02 pentru afiarea unui caracter mov dl,r[si] ;al crui cod ASCII este n DL int 21h cmp si,0 jne caracter sfrit: mov ah,4ch int 21h ; sfritul programului END pstart 4. Program care verific dac un numr este palindrom (un numr se numete palindrom dac scris de la dreapta la stnga sau invers are aceeai valoare). ; Programul verific dac un numr sau ir de caractere este ;palindrom dosseg .model small .stack .data nr DB 10,10 dup(0) mesaj db 13,10,'Introducei numrul:$' mesaj_nu db 13,10,'Numrul nu este palindrom!$' mesaj_da db 13,10,'Numrul este palindrom!$' .code pstart: mov ax,@data mov ds,ax mov ah,09 mov dx,offset mesaj int 21h mov ah,0ah mov dx,offset nr

Introducere n limbajul de programare Intel

int 21h mov si,1 mov cl,nr[si] ; ncarc n CL numrul de cifre al numrului introdus and cx,00FFh mov ax,cx mov bl,2 div bl ; n AL este catul mpririi lui AX la 2 and ax,00FFh inc ax inc cx mov di,cx urmtorul_caracter: inc si ; SI crete de la nceputul irului spre mijloc mov bl,nr[di] cmp nr[si],bl jne nu_este dec di ; DI scade de la sfritul irului spre mijloc cmp si,ax ; n ir se va merge pn la poziia cl+1 jne urmtorul_caracter mov ah,9 mov dx,offset mesaj_da int 21h jmp sfrit nu_este: mov ah,9 mov dx,offset mesaj_nu int 21h sfarsit: mov ah,4ch int 21h ; stop program END pstart 5. Program care calculeaz suma cifrelor unui numr introdus de la tastatur. ; Programul calculeaz suma cifrelor unui numr introdus de la ;tastatur dosseg .model small .stack .data

Elemente de arhitectur a sistemelor de calcul i operare

nr DB 10,10 dup(?) rezultat DB 10,10 dup(?) mesaj db 13,10,'Introducei numrul:$' mesaj_suma db 13,10,'Suma cifrelor numrului este: $' .code pstart: mov ax,@data mov ds,ax mov ah,09 ; aici se afieaz mesajul iniial de introducere mov dx,offset mesaj ; a numrului int 21h mov ah,0ah ; funcia 10(0ah) citete un ir de caractere de la ;tastatura intr-o variabil de memorie mov dx,offset nr int 21h mov si,1 mov cl,nr[si] ; ncarc n CL numrul de cifre al numrului ;introdus and cx,00FFh inc cx ; CX stocheaz acum ultima poziie din irul ;de cifre xor ax,ax ; stocm rezultatul n AX, pe care l ;iniializm cu zero urmtorul_caracter: inc si ; SI crete de la nceputul irului spre sfrit add al,nr[si] sub al,30h ; scdem codul ASCII al lui zero cmp si,cx ; n ir se va merge pn la poziia cl+1 jne urmtorul_caracter xor si,si ; SI este indicele din irul care va conine ;rezultatul cifra: ; aici ncepe afiarea rezultatului din AX mov bx,0ah div bx add dl,30h mov rezultat[si],dl inc si xor dx,dx cmp ax,0 jne cifra mov ah,9

Introducere n limbajul de programare Intel

mov dx,offset mesaj_suma int 21h caracter: dec si mov ah,02 ;apelarea funciei 02 pentru afiarea ;unui caracter mov dl,rezultat[si] ;al crui cod ASCII este n DL int 21h cmp si,0 jne caracter mov ah,4ch int 21h ; terminarea programului END pstart