You are on page 1of 156

UNIVERSITATEA DIN BACU FACULTATEA DE INGINERIE

DAN ROTAR

MICROPROCESOARE
Note de curs

EDITURA ALMA MATER BACU 2007

CUPRINS
pag. CAPITOLUL 1 PROGRAMAREA N LIMBAJ DE ASAMBLARE 1.1. 1.2. 1.3. 1.4. Introducere Caracterizarea limbajului de asamblare Etapele elaborrii unui program n cod main Formatul fiierelor hex (.hex, .hxl, .hxh) CAPITOLUL 2 PROGRAMAREA MICROPROCESORULUI INTEL 8086 2.1. 2.2. 2.3. 2.3.1. 2.3.2. 2.3.3. 2.3.4. 2.3.5. 2.3.6. 2.3.7. 2.3.8. 2.3.9. 2.3.10. 2.4. 2.4.1. 2.4.2. 2.4.2.1. 2.4.2.2. 2.4.2.3. 2.4.2.4. 2.4.2.5. 2.4.2.6. Structura microprocesorului 8086 Instruciunile microprocesorului 8086 Extinderea structurii unitii centrale la familia 80x86 Unitatea central 80x86 din punct de vedere al programatorului Registrele de uz general ale unitii centrale 8086 Registrele de segment 8086 Registrele de uz special Registrele 80286 Registrele procesoarelor 80386/80486 Organizarea memoriei fizice la 80x86 Segmentele la 80x86 Adrese normalizate la 80x86 Registrele de segment la procesoarele 80x86 Modurile de adresare la procesoarele 80x86 Modul de adresare a registrelor la procesorul 8086 Modurile de adresare ale memoriei la procesorul 8086 Modul de adresare numai prin deplasament Modul de adresare indirect prin registre Modurile de adresare indexate Modul de adresare indexat bazat Adresare indexat bazat plus deplasament Un mod simplu de a reine modurile de adresare a memoriei la procesorul 8086 6 6 8 10 13 19 19 21 36 36 36 37 38 39 39 40 41 43 44 45 46 46 47 48 50 51 51 53

2.4.2.7. Cteva comentarii finale asupra modurilor de adresare la 3

2.4.3. 2.4.3.1. 2.4.3.2. 2.4.3.3. 2.4.3.4. 2.4.3.5. 2.5. 2.6. 2.7. 2.8. 2.8.1. 2.8.2. 2.8.3. 2.9. 2.9.1.

procesorul 8086 Modurile de adresare a registrelor la 80386 Modurile de adresare a memoriei la 80386 Modul de adresare indirect prin registre Modurile de adresare indexat, indexat/bazat i bazat/indexat/deplasament la procesorul 80386 Modul de adresare scalat indexat la procesorul 80386 Cteva consideraii finale asupra modurilor de adresare a memoriei la 80386 Instruciunea MOV la procesorul 8086 Comentarii finale asupra instruciunilor MOV Cteva instruciuni suplimentare Structura unui program n limbaj de asamblare Directivele de segmentare Directivele pentru definirea datelor Concluzii privind limbajul de asamblare Scrierea aplicaiilor Windows n limbaj de asamblare Includerea limbajului de asamblare n programele Visual Basic CAPITOLUL 3 PROGRAMAREA MICROPROCESORULUI TMS 320F240

53 54 54 54 54 56 56 57 60 60 61 62 69 69 78 78

82 82 92 108

3.1. Setul de instruciuni a procesoarelor Texas Instruments C5X/C2XX 3.2. Turbo-Asamblorul (TASM) 3.3. Exemple de programe n limbaj de asamblare, pentru microprocesorul TMS 320F240 CAPITOLUL 4 PROGRAMAREA MICROCONTROLERELOR DE TIP PIC12, PIC16 I PIC 18 4.1. 4.1.1. 4.1.2. 4.1.3. 4.1.4. 4.1.5. 4.1.6. 4.1.7. 4.1.8. 4.1.9. 4.1.10. 4.1.11. 4.1.12. 4.1.13. 4.1.14. Organizarea memoriei microcontrolerelor PIC Memoria program Memoria de date Registrele SFR Bancuri de Memorie Contorul de Program Stiva Registrul STATUS (ADRESA: 03h, 83h) Registrul OPTION (ADRESA: 81h) Registrul INTCON (ADRESA: 0Bh, 8Bh) PCL i PCLATH Memoria de date EEPROM Registrul EECON1 (ADRESA: 88h) Citirea memoriei EEPROM Scrierea n memoria de date EEPROM 4

122 122 124 124 124 124 125 125 125 127 128 129 129 130 130 131

4.1.15. 4.1.16. 4.1.17. 4.2. 4.3. 4.4. 4.4.1. 4.4.2. 4.4.3. 4.4.4. 4.4.5.

Verificarea scrierii Harta memoriei RAM Moduri de adresare Porturile microcontrolerului Setul de instruciuni a unitilor centrale de tip RISC PIC12, PIC16 i PIC18 Exemple de programme n limbaj de asamblare Iniializarea unei zone de memorie RAM Salvarea i restaurarea regitrilor (echivalentul instruciunilor PUSH i POP) Testarea coninutului unui registru Conversie binar-ASCII Afiarea unui ir pe un display LCD BIBLIOGRAFIE

132 133 133 135 137 144 144 145 146 146 146 154

CAPITOLUL 1
PROGRAMAREA N LIMBAJ DE ASAMBLARE 1.1. Introducere

Microprocesoarele reprezint uniti centrale integrate ntr-un singur circuit integrat pe scar foarte larg (VLSI Very Large Scale Integration), care au cptat o larg dezvoltare o dat cu dezvoltarea tehnologiei de integrare i cu rspndirea utilizrii sistemelor cu microprocesor n cele mai diverse domenii de activitate. Pe de alt parte, tendina de miniaturizare continu a sistemelor numerice a dus la apariia i dezvoltarea calculatoarelor integrate, utilizate n cele mai diverse domenii ale activitii umane. Procesarea digital a semnalelor (DSP Digital Signal Processing) se distinge de alte domenii ale tiinei calculatoarelor prin faptul c exist un singur tip de date utilizate i anume semnalele. n marea majoritate a cazurilor aceste semnale provin de la senzori care preiau mrimi din lumea real: vibraii seismice, imagini, sunete etc. DSP reprezint matematica, algoritmii i tehnicile utilizate pentru prelucrarea acestor semnale dup ce acestea au fost transformate n prealabil n format digital. Aceast prelucrare se face n diferite scopuri, obiectivele urmrite avnd un spectru larg de aplicabilitate: analiza imaginilor, recunoaterea formelor, recunoaterea i generarea vorbirii, compresia datelor pentru stocare sau transmitere etc. Dac vom ataa un convertor analog-digital unui calculator n scopul prelurii unei anumite cantiti de date din lumea real, tehnica DSP ne va ajuta s interpretm aceste date. nceputurile DSP se localizeaz la nceputurile anilor 1960 i 1970 cnd calculatoarele numerice au nceput s fie folosite n diferite ramuri ale tiinei i tehnicii. n aceast perioad ns calculatoarele erau foarte scumpe i din acest motiv aplicaiile DSP erau limitate doar la cteva domenii de mare interes. ncercri de pionerat s-au fcut n domeniile cheie ca: tehnologia radar care presupune creterea securitii naionale, exploatarea petrolului care aduce venituri nsemnate, explorarea spaiului cosmic unde utilizarea acestei tehnologii este indispensabil i analiza imaginilor n domeniul medical care permite salvarea de viei omeneti. Revoluia calculatoarelor personale din anii 1980 i 1990 a dus la dezvoltarea spectaculoas a tehnicilor DSP ntr-un numr impresionant de domenii. Dac la nceput aceast tehnic era utilizat aproape exclusiv n aplicaii militare sau guvernamentale, scderea preului de cost a tehnicii de calcul o dat cu dezvoltarea spectaculoas a tehnologiei digitale a dus la utilizarea tehnologiei DSP n multe domenii comerciale cum sunt: telefonia mobil, CD playere, pot electronic vocal etc. 6

Dezvoltarea tehnologiei DSP a dus la apariia procesoarelor de semnal (DSP Digital Signal Processor) care reprezint calculatoare integrate specializate pentru acest domeniu. Observm faptul c acronimul DSP este folosit att pentru tehnica de prelucrare digital a semnalelor ct i pentru dispozitivul utilizat pentru aceasta. n final trebuie remarcat c nu exist o grani clar ntre tehnologia DSP i alte domenii ale tiinei. Dintre domeniile care se ntreptrund cu tehnologia DSP se pot aminti: o teoria comunicaiei; o analiza numeric; o statistica i probabilitile; o procesarea analogic a semnalelor; o teoria deciziei; o electronica digital; o electronica analogic. Indiferent de structura sistemului de calcul utilizat, modul de programare al unitii centrale se face n acelai fel existnd similitudini evidente dar i diferene importante ntre diferitele tipuri de uniti centrale. O unitate central are un limbaj propriu, care difer de la o unitate central la alta, instruciunile unitii centrale fiind reprezentate de iruri de numere binare. Productorul unitii centrale stabilete tipurile de instruciuni, codificarea, structura i modul de utilizare a acestora. Un program scris n binar cu ajutorul acestor instruciuni se numete program main iar codul n care este scris se numete cod obiect (sau cod binar) direct executabil. Primele programe au fost scrise n acest fel dar evident, scrierea unor astfel de programe este dificil iar riscul de eroare este ridicat. Pentru simplificarea scrierii programelor n cod obiect direct executabil, productorii unitilor centrale asociaz codului binar corespunztor unei instruciuni, un nume care s fie semnificativ i care s sugereze aciunea realizat de instruciune. Acest nume poart denumirea de mnemonic. Programarea cu mnemonici este mai uor de realizat dar este necesar un program de traducere din mnemonici n cod binar. Un astfel de program prevzut cu o serie de faciliti care s uureze munca programatorului se numete asamblor iar programele scrise cu ajutorul mnemonicelor, pentru asamblor, se numesc programe n limbaj de asamblare. Astzi programarea unitilor centrale se face n limbaj de asamblare. Deoarece acest program se adreseaz direct structurii fizice a unui sistem de calcul, se spune c limbajul de asamblare este un limbaj de programare de nivel sczut spre deosebire de limbajele de nivel nalt (C, PASCAL, Java etc) care sunt limbaje de programare de nivel nalt. Programele scrise n limbaj de asamblare nu pot fi rulate dect pe unitatea central pentru care au fost scrise i din acest motiv se spune c programele scrise n limbaj de asamblare nu sunt portabile. Avantajul utilizrii programelor n limbaj de asamblare este reprezentat de faptul c ele permit accesul programatorului la structurile intime ale sistemului de calcul (ceea ce nu se ntmpl la limbajele de nivel nalt) i permit scrierea unor programe de dimensiuni mici ce se execut n timp scurt iar uneori astfel de cerine sunt impuse. Din acest motiv i limbajele de programare de nivel nalt permit mecanisme de inserare a unor secvene de program scrise n limbaj de asamblare. 7

1.2.

Caracterizarea limbajului de asamblare


Prezentm n continuare cteva motive pentru studiul limbajului de asamblare: o pentru a face programe mai scurte i care s lucreze mai repede; o pentru a nelege mai bine cum lucreaz calculatoarele; o pentru a scrie un cod eficient.

Limbajul de asamblare este puin rspndit printre nespecialiti. Acest lucru se datoreaz unor prejudeci rspndite de-a lungul timpului pe care le vom analiza n continuare n scopul caracterizrii corecte a acestui limbaj. Dificultile limbajului de asamblare: 1) 2) 3) 4) 5) 6) 7) este greu de nvat; este greu de citit i de neles; este greu de depanat; este greu de ntreinut; este greu de scris; programarea n acest limbaj este mare consumatoare de timp; tehnologia mbuntit a compilatoarelor a eliminat nevoia de limbaj de asamblare; 8) mainile actuale sunt att de rapide nct nu mai este necesar programarea n limbaj de asamblare; 9) dac este nevoie de vitez se pot folosi algoritmi performani mai degrab dect programarea n limbaj de asamblare; 10) mainile actuale dispun de mari cantiti de memorie i economia adus de limbajul de asamblare devine neimportant; 11) limbajul de asamblare nu este portabil. n general aceste afirmaii sunt fcute de persoane care nu utilizeaz limbajul de asamblare i nici nu au o idee precis asupra acestui limbaj. Din acest motiv, afirmaiile de mai sus vor fi explicate n ideea c ele pot s nu fie adevrate n momentul cnd cunoatem i folosim limbajul de asamblare. 1) Limbajul de asamblare este greu de nvat. Dac stpnii un limbaj de programare cum este, de exemplu, Pascal, atunci nvarea altor limbaje ca de exemplu: C, BASIC, FORTRAN, Modula-2 sau Ada este relativ simpl pentru c ele sunt destul de asemntoare cu Pascal. Pe de alt parte nvarea unui limbaj ce difer mult de Pascal, cum este Prolog, nu e simpl. i limbajul de asamblare este diferit de Pascal i atunci el va fi puin mai dificil de nvat. n orice caz nvarea limbajului de asamblare nu este mai grea dect nvarea pentru prima dat a unui limbaj de programare. 2) Limbajul de asamblare este greu de citit i neles. Aceast afirmaie este fcut de persoanele ce nu cunosc acest limbaj. Evident c pot fi scrise programe de neneles n limbaj de asamblare ca i n alte limbaje. Dup ctigarea 8

experienei n limbaj de asamblare v vei da seama c este mai uor de citit dect alte limbaje. 3) Limbajul de asamblare este greu de depanat. Acelai argument trebuie explicat ca mai sus. Odat ctigat experien nimic nu va prea mai simplu. 4) Limbajul de asamblare este greu de ntreinut. Programele n C sunt greu de ntreinut. Aptitudinea de a scrie programe uor de ntreinut se ctig dup oarecare experien. 5) Limbajul de asamblare este greu de scris. Aceast afirmaie are un smbure de adevr. O lung perioad de timp programatorii n limbaj de asamblare au scris programele n ntregime de la nceput la sfrit, reinventnd de fiecare dat roata. Limbajele de nivel nalt beneficiaz de biblioteci ce simplific mult munca. Acelai lucru poate fi fcut i n limbaj de asamblare dac inem cont c sunt disponibile biblioteci (cele mai multe gratuite) cu majoritatea rutinelor necesare scrierii programelor. 6) Programarea n limbaj de asamblare este consumatoare de timp. Este adevrat c elaborarea unui program n limbaj de asamblare necesit mai mult timp (uneori dublu) fa de scrierea programelor n limbaje de nivel nalt. Oricum ctigul de timp nu poate umbri celelalte beneficii aduse de limbajul de asamblare. 7) Tehnologia mbuntit a compilatoarelor a eliminat nevoia de limbaj de asamblare. Acest lucru nu este adevrat i probabil nu va fi niciodat adevrat. Performana programelor scrise n limbaj de asamblare const n modul de scriere al acestora i de talentul i inventivitatea programatorului ceea ce nu se poate compara cu aciunea unui compilator. 8) Mainile actuale dispun de mari cantiti de memorie i economia adus de limbajul de asamblare devine neimportant. Este uimitor faptul c oamenii prefer s cheltuiasc bani ca s cumpere maini mai rapide n loc s consume timp s scrie programe n limbaj de asamblare. Un fapt rmne: tot timpul se dorete mai mult vitez. Pentru o main dat cele mai rapide programe rmn cele scrise n limbaj de asamblare. 9) Dac este nevoie de vitez se pot folosi algoritmi performani mai degrab dect programarea n limbaj de asamblare. Orice algoritm ce poate fi implementat n limbajele de nivel nalt poate fi implementat i n limbaj de asamblare i deci va fi mai rapid aici. Pe de alt parte, exist algoritmi ce nu pot fi implementai dect n limbaj de asamblare. 10) Mainile actuale dispun de mari cantiti de memorie i economia adus de limbajul de asamblare devine neimportant. D-i cuiva un centimetru i-i va cere un metru. Este evident c orict de mult memorie este disponibil ea nu va 9

ajunge. De asemenea, din motive tehnice este recomandabil ca programatorii s scrie programe ct mai scurte. 11) Limbajul de asamblare nu este portabil. Acest fapt este de necontestat. Dac programul trebuie s funcioneze pe procesoare diferite atunci limbajul de asamblare nu este o soluie. Limbajul de asamblare prezint i avantaje incontestabile pe care le vom enumera n continuare. Aceste avantaje reprezint argumente serioase n scopul nvrii acestui limbaj. Avantajele programrii n limbaj de asamblare: o vitez programele scrise n limbaj de asamblare sunt n general cele mai rapide; o spaiu programele scrise n limbaj de asamblare sunt de regul cele mai mici; o performan aceste programe v permit s facei ceea ce este imposibil n limbajele de nivel nalt; o cunotine cunoaterea limbajului de asamblare v permite s scriei programe mai performante n limbajele de nivel nalt.

1.3.

Etapele elaborrii unui program n cod main

Etapele elaborrii unui program n cod main difer de la caz la caz. Astfel, dac dorim s elaborm un program n cod main pentru unitatea central a sistemului pe care lucrm, atunci la sfrit programul realizat se va gsi n memoria calculatorului, gata de execuie. Acest caz l ntlnim atunci cnd scriem un program n limbaj de asamblare pentru microprocesorul 8086 pe un calculator personal de tip IBM PC. Aceste calculatoare sunt dotate cu procesoare Intel 80x86 sau compatibile care pot executa programe n cod obiect scrise pentru unitatea central 8086 deoarece politica Intel a fost de a pstra compatibilitatea procesoarelor de jos (ncepnd cu 8086) n sus (ultima generaie de procesor Intel). Etapele elaborrii unui program pentru microprocesorul 8086, lucrnd pe un calculator compatibil IBM PC vor fi: o se scrie programul n limbaj de asamblare cu ajutorul unui editor de texte, obinndu-se un fiier text numit fiier surs care are cel mai adesea extensia .asm (fiierul surs reprezint instrumentul de lucru al programatorului coninnd numeroase comentarii i explicaii); o traducerea (translatarea) fiierului surs n format binar se face cu ajutorul programului asamblor. n aceast etap asamblorul semnaleaz eventualele erori de sintax ale programului i genereaz, n cazul n care programul este corect din punct de vedere sintactic (la acest nivel nu se poate face i verificarea logic), un fiier n cod binar. n funcie de 10

necesitile programatorului, asamblorul poate genera dou tipuri de fiiere: fiiere n cod obiect absolut, direct executabile de ctre unitatea central, care sunt aezate n memorie la adresa de unde vor fi executate (fiierul generat conine adresele absolute ale programului) i care vor avea extensia .com sau .exe (modul de stabilire a extensiei se va explica mai trziu), sau fiiere n cod obiect relativ, care conin codul obiect dar adresele sunt relative (simbolice) i care nu pot fi executate direct dar pot fi puse n biblioteci (pentru o utilizare ulterioar) i care pot fi utilizate mpreun cu alte programe n cod obiect relativ din bibliotecile deja create, pentru obinerea programului final, n cod obiect absolut; o dac s-a obinut fiierul n cod obiect absolut (extensia .com sau .exe) se poate trece la lansarea n execuie n scopul verificrii i eventual a depanrii (cu ajutorul unui program de depanare debugger) funcionrii logice a acestuia; o dac s-a obinut un fiier n cod obiect relocabil, fiierul poate fi adugat unei biblioteci (library) cu ajutorul unui program bibliotecar (librarian) sau se poate genera programul n cod obiect absolut cu ajutorul unui editor de legturi (linkeditor). Editorul de legturi caut n biblioteci legturile solicitate, adaug n programul n cod obiect absolut secvenele extrase din biblioteci, semnaleaz eventualele referine nerezolvate i, n cazul n care nu au fost erori, genereaz codul obiect absolut. S exemplificm modul n care se poate realiza un program care conine o operaie de nmulire utilizat dintr-o bibliotec matematic extern. Pentru aceasta trebuie s cunoatem numele rutinei de nmulire din biblioteca utilizat. Se scrie programul in limbaj de asamblare iar acolo unde se folosete operaia de nmulire se scrie numele rutinei din biblioteca extern i se respect conveniile de utilizare specificate pentru biblioteca respectiv. De asemenea se specific n program faptul c numele folosit este o referin extern n aa fel nct asamblorul s nu semnaleze o eroare. Modul de lucru este similar cu cel din limbajele de nivel nalt cnd se folosesc funcii sau proceduri din bibliotecile externe. Se genereaz fiierul n cod obiect relocabil, dup care se trece la prelucrarea cu ajutorul editorului de legturi. Linkeditorului i se specific numele bibliotecii n care s caute rutina de nmulire i dac acesta o gsete, include n programul n cod obiect absolut secvena de cod corespunztoare rutinei. n afar de uneltele (programele) folosite pentru prelucrare, se mai folosete i un program numit dezasamblor (disassembler), util n depanare, care are aciune invers asamblorului: traduce formatul n cod obiect absolut n textul corespunztor. 11

n cazul n care se dezvolt programe pe o alt main dect cea pentru care se scriu programele, etapele sunt aceleai (asamblorul se numete n acest caz crossasamblor crossassembler), numai c la final programul trebuie transferat de pe maina pe care s-a lucrat pe maina pentru care s-a scris programul. Transferul se face de regul cu ajutorul programatoarelor care transfer codul obiect absolut din memoria mainii gazd n memoria mainii pentru care s-a scris programul. Pentru transfer se folosete formatul IntelHEX. Pentru a exemplifica acest lucru, vom arta modul n care se dezvolt programe pentru microcontrolere de tip PIC (Microchip) pe maini de calcul compatibile IBM PC (calculatoare personale). Pe calculatorul personal se folosete programul MPLAB, furnizat n mod gratuit de firma Microchip, care este un mediu de dezvoltare (IDE Integrated Development Environment) care conine un crosasamblor, un dezasamblor, un linkeditor, un simulator, un bibliotecar, help i alte faciliti pentru realizarea programelor. n acest fel, programele se pot dezvolta si pune la punct pe calculatorul personal i apoi se pot transfera n memoria microcontrolerului. Verificarea final se face ns tot prin execuia programului pe microcontroler n aa fel nct s se poat verifica n condiii reale funcionarea programului. Generarea codului absolut. Codul absolut este ieirea implicit pentru (cross)asamblorul MPASM. Procesul este artat n figura 1.1.

Figura 1.1. Generarea codului absolut pentru microcontroler.

Cnd un fiier surs este asamblat n acest fel, toate variabilele i subprogramele folosite n fiierul surs trebuie s fie definite n acest fiier surs sau s fi fost incluse n acest fiier. Dac asamblarea se realizeaz fr erori, se va genera un fiier hex ce conine codul executabil pentru dispozitivul int. Acest fiier poate fi utilizat cu un depanator pentru a teste execuia codului sau cu un programator pentru programarea dispozitivului. Generarea codului relocabil. Asamblorul MPASM are de asemenea posibilitatea de a genera un modul obiect relocabil care poate fi legat cu alte module utiliznd MPLINK pentru obinerea codului executabil. Aceast metod este foarte folositoare pentru crearea modulelor reutilizabile. 12

Figura 1.2. Generarea i utilizarea fiierelor relocabile.

Modulele nrudite pot fi grupate i stocate mpreun folosind bibliotecarul MPLIB. Bibliotecile necesare pot fi specificate la link-editare i numai rutinele necesare vor fi incluse n fiierul executabil.

1.4.

Formatul fiierelor hex (.hex, .hxl, .hxh)

Asamblorul MPASM i linkeditorul MPLINK pot crea fiiere text ASCII de tip hex de diferite formate: Numele formatului Format Intel Hex Format Intel Split Hex Intel Hex 32 Format Tipul formatului INHX8M INHX8S INHX32 Extensia fiierului .hex .hxl, .hxh .hex Utilizare Programatoare pentru dispozitive de 8 bii Programatoare par/impar Programatoare pentru dispozitive de 16 bii

Aceste formate de fiiere sunt folositoare pentru transferarea codului pentru PIC MCU ctre programatoare. Formatul Intel HEX Acest format creeaz un fiier hex pe 8 bii cu combinaia octetul cel mai puin semnificativ, octetul cel mai semnificativ (low byte, high byte). Chiar dac fiecare adres conine 8 bii, n acest format toate adresele sunt dublate. 13

Fiecare nregistrare ncepe cu un prefix de 9 caractere i se termin cu o suma de contro de 2 caractere. Fiecare nregistrare are urmtorul format: :BBAAAATTHHHH....HHHCC unde: BB AAAA TT HH CC un numr de un octet cu dou cifre hexazecimale ce reprezint numrul de octei de date ce apar pe linie; o adres hexazecimal de 4 cifre care arat adresa de start a nregistrrii de date; tipul nregistrrii reprezentat pe 2 cifre hexa care este ntotdeauna "00" cu excepia nregistrrii de sfrit de fiier (end of file) care este "01"; un octet de date reprezentat cu 2 cifre hexa n ordinea Low byte/High byte; o sum de control cu 2 cifre hexa care reprezint suma tuturor octeilor precedeni ai nregistrrii n complement fa de 2. (Not - complementul fa de 2 se calculeaz ca suma octeilor precedeni care apoi se scade din 256. De exemplu suma = 5 iar in complement faa de 2=256-5=251)

Exemplu: INHX8M nume_fisier.hex :1000000000000000000000000000000000000000F0 :0400100000000000EC :100032000000280040006800A800E800C80028016D :100042006801A9018901EA01280208026A02BF02C5 :10005200E002E80228036803BF03E803C8030804B8 :1000620008040804030443050306E807E807FF0839 :06007200FF08FF08190A57 :00000001FF Formatul Intel Split Hex Formatul divizat (split) creeaz 2 fiiere: .hxl i .hxh. Formatul este asemntor cu formatul normal pe 8 bii cu excepia faptului c octeii cei mai puin semnificativi ai cuvintelor de date sunt stocai n fiierul .hxl iar octeii cei mai semnificativi ai cuvintelor de date sunt stocai n fiierul .hxh iar adresele sunt mprite la 2. Acest format este folosit la programarea cuvintelor de 16 bii n dou memorii EPROM de 8 bii care vor fi folosite pereche (mpreun). Exemplu: INHX8S 14

nume_fisier.hxl :0A0000000000000000000000000000F6 :1000190000284068A8E8C82868A989EA28086ABFAA :10002900E0E82868BFE8C8080808034303E8E8FFD0 :03003900FFFF19AD :00000001FF nume_fisier.hxh :0A0000000000000000000000000000F6 :1000190000000000000000010101010102020202CA :100029000202030303030304040404050607070883 :0300390008080AAA :00000001FF Format Intel Hex 32 Formatul extins la 32 de bii este similar formatului pe 8 bii cu excepia faptului c adresa stabilete cei mai semnificativi 16 bii ai adresei de date. Acest format este folosit pentru dispozitive pe 16 bii la care memoria de program adresabil depete 64 de koctei. Fiecare nregistrare de date ncepe cu un prefix de 9 caractere i se termin cu o suma de control de 2 caractere. Fiecare nregistrare are urmtorul format: :BBAAAATTHHHH......HHHCC unde: BB AAAA TT un numr de un octet cu dou cifre hexazecimale ce reprezint numrul de octei de date ce apar pe linie; o adres hexazecimal de 4 cifre care arat adresa de start a nregistrrii de date; tipul nregistrrii reprezentat pe 2 cifre: 00 - nregistrare de date 01 - nregistrare end of file 02 - Segment address record 04 - Linear address record un octet de date reprezentat cu 2 cifre hexa n ordinea Low byte/High byte; o sum de control cu 2 cifre hexa care reprezint suma tuturor octeilor precedeni ai nregistrrii n complement fa de 2. (Not - complementul fa de 2 se calculeaz ca suma octeilor precedeni care apoi se scade din 256. De exemplu suma = 5 iar in complement faa de 2=256-5=251) 15

HH CC

Analiza generrii unui fiier INTEL HEX Folosim urmtorul studiu de caz: Fiierul listing: MPASM 4.02 Released TEST1.ASM 12-13-2005 8:09:51 LOC OBJECT CODE LINE SOURCE TEXT VALUE

PAGE

00001 ;Program pentru initializarea portului B si setarea pinilor 00002 ;la starea unu logic 00003 00004 ;Declaratia si configuratia procesorului 00005 00006 PROCESSOR 16F84A 00007 #include "p16f84A.inc" 00001 LIST 00002 ; P16F84A.INC Standard Header File, Version 2.00 Microchip Technology, Inc. 00134 LIST 00008 Warning[205]: Found directive in column 1. (LIST) 00009 LIST 2007 3FF1 00010 __CONFIG _CP_OFF &_WDT_OFF &_PWRTE_ON &_XT_OSC 00011 0000 00012 org 0x00 ;vector reset 0000 2805 00013 goto main 0004 00014 org 0x04 ;rutina de intrerupere nu exista 0004 2805 00015 goto main 00016 0005 00017 main 0005 0000 00018 nop ;programul principal 0006 0000 00019 nop 0007 2805 00020 goto main

Din acest listing rezult c trebuie scris n memorie: 16

Adresa 2007 0000 0004 0005 0006 0007

Valoare cuvnt 3FF1 2805 2805 0000 0000 2805

Fiierul HEX obinut: :020000040000FA :020000000528D1 :08000800052800000000052896 :02400E00F13F80 :00000001FF o prima linie: 020000040000FA este compus din: 02 - numrul de octei de date ce apar pe linie, 0000 - adresa de start a nregistrrii de date (n acest caz aici trebuie s fie ntotdeauna 0000), 04 - extended linear address record, 0000 - cei mai semnificativi 16 bii ai adresei, FA - suma de control = 01h + NOTA (02h + 00h + 00h + 04h + 00h + 00h). Modul de calcul se face n felul urmtor: 02h+04h+06h, 06h mod 100h = 06h, NOT(06h) = FFh - 06h = F9h, F9h+01h = FAh. o a doua linie: 020000000528D1 este compusa din: 02 numrul de octei de date ce apar pe linie, 0000 - adresa de start a nregistrrii de date, 00 - nregistrare de date, 0528 datele scrise n ordinea: octetul cel mai putin semnificativ, octetul cel mai semnificativ, deci este de fapt 2805 n listing, D1 - suma de control: 01h + NOT (02h+05h+28h) = 01h + NOT(2Fh) ((2Fh MOD 100h=2Fh)), 01h+FFh-2Fh=D1. o a treia linie: 08000800052800000000052896: 08 - numrul de octeti de date, 0008 - adresa de start, 00 - nregistrare de date, octeii de date sunt: 0528000000000528, ceea ce nseamna: 2805, 0000, 0000, 2805. Se pare c din cauz c pentru fiecare adres sunt cte 2 octei, aceasta apare dublat. Deci adresa de start 0008 este de fapt adresa 0004. Suma de control: 08h+08h+05h+28h+05h+28h=6Ah, 6Ah MOD 100h = 6Ah, FFh-6Ah=95h+01h=96h. o a patra linie: 02400E00F13F80: 02 - 2 0cteti de date, 400Eh adresa de start care e n realitate 400Eh/2h=2007h (ca n listing), 00 - nregistrare de date, datele: F13F care se citesc 3FF1, i suma de control: 02h+40h+0Eh+F1h+3Fh = 180h MOD 100h = 80h, FFh - 80h = 7Fh + 01h =80h. o ultima linie: 00000001FF este linia de End of File. 17

Acest studiu de caz a fost aplicat pentru un exemplu realizat n MPLAB. Se pot trage urmtoarele concluzii: o se folosete adresarea linear extins; o adresa de start a datelor de pe o linie din fiierul HEX este dublul adresei reale (din listing); o fiecrei adrese i sunt asociai 2 octei, 4 cifre hexa, scrise n ordinea: cel mai puin semnificativ octet urmat de cel mai semnificativ octet; o restul regulilor sunt respectate de la formatul INTEL HEX.

18

CAPITOLUL 2
PROGRAMAREA MICROPROCESORULUI INTEL 8086
Vom reaminti, pentru nceput, principalele caracteristici ale structurii accesibile programatorului, pentru microprocesorul I8086, utile n programarea n limbaj de asamblare a acestuia.

2.1.

Structura microprocesorului 8086

Exist trei categorii de registre: registre de uz general, registre de adrese, indicatori, pointeri i index i registre de uz special. Unitatea central 8086 are 16 patru registre de uz general, pe 16 bii: 15 AH 8 7 AL 0
AX BX CX DX

AX, BX, CX, DX care pot fi folosite i ca registre de 8 bii: AH, AL, BH, BL, CH, CL, DH, DL

BH CH DH

BL CL DL

aa cum se arat n figura alturat. Fiecare dintre registrele de 16 bii poate fi folosit ca destinaie a datelor (acumulator) dar registrul acumulator implicit este registrul AX. Registrul bistabililor de condiii i de control al microprocesorului, FX, asociat cu registrul acumulator (de regul registrul AX): FX 15 X 14 X 13 X 12 X 11 10 9 OF DF IF 8 7 6 5 TF SF ZF X 4 3 AF X 2 1 PF X 0 CF

unde cu X s-a simbolizat bistabilul inaccesibil utilizatorului. Semnificaia fanioanelor din registrul FX este: CF = "carry flag": depire aritmetic (CF = 0 nu s-a produs o depire aritmetic, CF = 1 s-a produs o depire aritmetic); PF = parity flag: paritate; 19

AF = auxiliary flag: transport ntre bitul 7 i 8; ZF = "zero flag: valoare zero (ZF = 0 n acumulator este o valoare diferit de zero, ZF = 1 n urma unei operaii, valoarea rezultat n acumulator este zero); SF = sign flag: semnul n reprezentarea numerelor cu semn (bitul 15); TF = trip flag; TF = 1 determin UCP s lucreze n mod pas cu pas (single step), n care se genereaz o ntrerupere intern dup fiecare execuie a unei instruciuni; IF = masca pentru ntreruperi externe (IF = 1 => validarea ntreruperilor; IF = 0 => invalidarea ntreruperilor); DF = direction flag- indic direcia deplasrii adresei la operaiile cu iruri de date (DF = 1 => autodecrementare, DF = 0 => autoincrementare, dup o operaie elementar); OF = V (depire). Registrele de adrese, indicatori, pointeri i index (se utilizeaz numai pe 16 bii): SP (pointer stiv), BP (pointer adres de baz), SI (index surs), DI (index destinaie). Utilizrile implicite ale registrelor sunt: AX: utilizat pentru operaii aritmetice nmulire, mprire pe 16 bii i pentru operaii de I/E pe 16 bii; n mod analog AL este utilizat pe 8 bii i n plus pentru aritmetic zecimal i conversii de cod; AH este utilizat la nmuliri i mpriri pe 8 bii; BX: utilizat n conversii de cod i ca registru de baz de adrese; CX: utilizat n operaii cu iruri, cu rol de contor de cicluri; CL: utilizat n deplasri (stnga, dreapta cu un numr de pai dai ca parametru de valoare lui CL); DX: utilizat la nmuliri, mpriri pe 16 bii i ca registru de adresare indirect la porile de intrare ieire (I/E); SP,BP: utilizat implicit n toate operaiile cu stiva; SI, DI: utilizate n operaiile asupra irurilor de date, SI conine adresa sursei iar DI adresa destinaiei. Registrele de uz special sunt cele destinate adresrii segmentate: CS, DS, SS, ES = sunt registre segment care conin adresele de baz ale segmentelor logice de cod, date, stiv i extrasegment; IP = Instruction Printer = contor de program, cu 16 bii. Valoare ce reprezint adresa relativ (offset-ul) a instruciunii curente n segmentul de cod (relativ la CS). n cazul unei instruciuni de salt, IP este salvat n vrful stivei (mpreun cu CS, deci saltul este inter-segment) i apoi ncrcat cu adresa relativ n segmentul de cod a instruciunii int. ntre registre de adrese, indicatori, pointeri i index i registre de uz special exist anumite relaii n funcionarea microprocesorului 8086. Segmentul de date are ca registru segment registrul DS i ca registru pointer implicit, registrul DX. Relaiile ntre registrele microprocesorului 8086 sunt prezentate n figura 2.1. 20

POINTER STIVA (SP) POINTER ADR. BAZA (BP) INDEX SURS| (SI) INDEX DESTINAIE (DI) COD SEGMENT (CS) DATE SEGMENT (DS) STIV| SEGMENT (SS) EXTRA SEGMENT (ES) POINTER INSTRUCIUNE (IP) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF

Registre de adrese (indicatori, printer, index)

Registre segment pentru operaii auxiliare cu datele

Numrtor instruciuni

Figura 2.1. Relaia ntre registrele microprocesorului 8086.

2.2.

Instruciunile microprocesorului 8086

Microprocesorul 8086 are un set complex de instruciuni. Mnemonicile utilizate sunt prezentate n tabelul 2.1. TABELUL 2.1. CMPSB AAA CMPSW AAD CWD AAM DAA AAS DAS ADC DEC ADD DIV AND HLT CALL IDIV CBW IMUL CLC IN CLD INC CLI INT CMC INTO CMP IRET JA

JAE JB JBE JC JCXZ JE JG JGE JL JLE JMP JNA JNAE JNB

JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE

JPO JS JZ LAHF LDS LEA LES LODSB LODSW LOOP LOOPE LOOPNE LOOPNZ LOOPZ

MOV MOVSB MOVSW MUL NEG NOP NOT OR OUT POP POPA POPF PUSH PUSHA PUSHF RCL

RCR REP REPE REPNE REPNZ REPZ RET RETF ROL ROR SAHF SAL SAR SBB

SCASB SCASW SHL SHR STC STD STI STOSB STOSW SUB TEST XCHG XLATB XOR

Semnificaia acestor mnemonici va fi prezentat pe scurt, n continuare. 21

AAA - ASCII adjust for addition (ajustare ASCII pentru adunare) Indicatori afectai: AF, CF Descriere: Dac cei mai puin semnificativi 4 bii ai lui AL sunt mai mari dect 9 sau dac carry auxiliar este 1, atunci adun 6 la AL i 1 la AH. AF i CF sunt actualizai. AAD - ASCII adjust for division (ajustare ASCII pentru mprire) Indicatori afectai: PF,SF,ZF Descriere: Octetul semnificativ a lui AH este nmulit cu 10 i adunat la AL. AAM - ASCII adjust for multiply (ajustare ASCII pentru nmulire) Indicatori afectai: PF,SF,ZF Descriere: Dac jumtatea mai puin semnificativ a lui AL este mai mic de 9 sau dac (AF)=1 atunci se scade 6 din AL si 1 din AH. Indicatorii (AF) si (CF) devin 1. Vechea valoare a lui AL este nlocuit de un octet n care jumtatea superioar este 0 iar jumtatea inferioar este un numr creat de scderea anterioar. AAS - ASCII adjust for subtraction (ajustare ASCII pentru scdere) Indicatori afectai: AF,CF Descriere: Dac jumtatea mai puin semnificativ a lui AL este mai mic de 9 sau dac (AF)=1 atunci se scade 6 din AL i 1 din AH. Indicatorii (AF) si (CF) devin 1. Vechea valoare a lui AL este nlocuit de un octet n care jumtatea superioar este 0 iar jumtatea inferioar este un numr creat de scderea anterioar. ADC - add with carry (adun cu carry) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Suma celor doi operanzi i a lui carry este memorat n operandul destinaie (stnga). ADD addition (adunare) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Suma celor doi operanzi este memorat n operandul destinaie (stnga) AND - logic and (i logic) Indicatori afectai: CF,OF,PF,SF,ZF Descriere: Se realizeaz i logic ntre cei doi operanzi, rezultatul va avea 1 in poziiile n care ambii operanzi au 1, restul fiind 0. Rezultatul este memorat la operandul din stnga. Carry i overflow sunt pui pe 0. CALL - call a procedure (apel de procedur) Indicatori afectai: niciunul Descriere: Dac este un apel intersegmente, stiva este decrementat cu 2 si continutul lui CS este salvat n ea. CS va fi umplut cu al doilea cuvnt al dublului cuvnt de adresare. Apoi se salveaz n stiv, n acelai mod, i coninutul lui IP. Ultimul pas este de a nlocui coninutul lui IP cu offset-ul adresei de destinaie, adic offset-ul primei instruciuni din procedura. Un apel n cadrul aceluiai segment sau grup are numai paii 2,3 si 4. CBW - convert byte to word (convertete octet la cuvnt) Indicatori afectai: niciunul Descriere: Dac AL e mai mic dect 80h, atunci AH devine 0. Altfel, AH este setat la 0ffh. Este echivalent cu a replica bitul 7 a lui AL la AH. 22

CLC - clear carry flag (terge indicatorul carry) Indicatori afectai: CF Descriere: Indicatorul carry este pus la zero. CLD - clear direction flag (terge indicatorul direcie) Indicatori afectai: DF Descriere: Indicatorul direcie este pus la zero. CLI - clear interrupt flag (terge indicatorul ntrerupere) Indicatori afectai: IF Descriere: Indicatorul ntrerupere este ters. CMC - complement carry flag (complementeaz indicatorul carry) Indicatori afectai: CF Descriere: Dac carry este 0, el devine 1; dac este 1 devine 0. CMP - compare two operands (compar doi operanzi) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Operandul sursa (stnga) este sczut din operandul destinaie (dreapta). Indicatorii sunt afectai dar operanzii nu. CMPS - compare byte string, compare word string (compar ir de octet, compar ir de cuvnt) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Operandul din dreapta, utiliznd DI ca registru index este sczut din operandul din dreapta, care utilizeaz registrul SI ca index. Sunt afectai numai indicatorii. DI i SI sunt incrementate dac indicatorul de direcie este 0, i decrementate dac e 1. Incrementul este 1 pentru ir de octei i 2 pentru cel de cuvinte. CWD - convert word to doubleword (convertete cuvnt la dublucuvnt) Indicatori afectai: niciunul Descriere: Cel mai semnificativ bit din AX este replicat n DX. DAA - decimal adjust for addition (ajustare zecimal pentru adunare) Indicatori afectai: AF,CF,PF,SF,ZF Descriere: Daca cei mai puin semnificativi (4) bii a lui AL sunt mai mari dect 9 sau dac carry auxiliar este 1 , atunci adun 6 la AL si AF devine 1. Dac AL este mai mare dect 9fh sau carry este 1 atunci adun 60h la AL i seteaz CF. DAS - decimal adjust for subtraction (ajustare zecimal pentru scdere) Indicatori afectai: AF,CF,PF,SF,ZF Descriere: Dac cei mai puin semnificativi (4) bii a lui AL sunt mai mari dect 9 sau daca carry auxiliar este 1, atunci scade 6 din AL si AF devine 1. Dac AL este mai mare dect 9fh sau carry este 1 atunci scade 60h din AL i seteaz CF. DEC - decrement destination by one (decrementeaz destinaia cu unu) Indicatori afectai: AF,OF,PF,SF,ZF Descriere: Operandul specificat este redus cu 1. DIV - division, unsigned (mprire, fr semn) Indicatori afectai: rezultatele indicatorilor nu sunt valide Descriere: Dac rezultatul mpririi e o valoare care nu poate fi pstrat n registrul corespunztor, se genereaz o ntrerupere de nivel 0. Indicatorii sunt pui n stiv, IF si TF devin 0, CS este de asemenea pus n stiv, fiind apoi umplut cu valoarea de la adresa 2. i IP curent este salvat i apoi ncrcat cu valoarea de la adresa 0. Aceast secven include un apel lung la rutina de ntreruperi ale crui segment i offset sunt memorate la locaiile 2 i 0. Dac 23

rezultatul ncape atunci ctul este memorat n AL sau AX (pentru operaii pe cuvnt) i respectiv restul n AH sau DX. ESC - escape Indicatori afectai: nici unul Descriere: Instruciunea ESC furnizeaz un mecanism prin care alte procesoare pot primi instruciuni de la 8086 i utilizeaz modul de adresare a lui 8086. Procesorul 8086 nu are alt operaie pentru ESC dect de a accesa un operand din memorie i de a-l plasa pe magistral. HLT - halt Indicatori afectai: nici unul Descriere: Instruciunea HLT determina procesorul 8086 s intre n starea halt. Starea halt este tears prin ntrerupere extern valid sau reset. IDIV - integer division, signed (mprire ntreag, cu semn) Indicatori afectai: AF,CF,OF,PF,SF,ZF dar sunt toi nedefinii Descriere: Dac rezultatul mpririi e o valoare care nu poate fi pstrat n registrul corespunzator, se genereaz o ntrerupere de nivel 0. Indicatorii sunt pui n stiv, IF i TF devin 0, CS este de asemenea pus n stiv, fiind apoi umplut cu valoarea de la adresa 2. i IP curent este salvat i apoi ncrcat cu valoarea de la adresa 0. Aceast secven include un apel lung la rutina de ntreruperi ale crui segment i offset sunt memorate la locaiile 2 si 0. Dac rezultatul ncape atunci ctul este memorat n AL sau AX (pentru operaii pe cuvnt) i respectiv restul n AH sau DX. IMUL - integer multiply accumulator by register-or-memory, signed (nmulire ntreag ntre acumulator i registru sau memorie, cu semn) Indicatori afectai: CF,OF Descriere: Acumulatorul (AL pentru octet, AX pentru cuvnt) e nmulit prin operandul specificat. Dac jumtatea superioar a rezultatului este extensia de semn a jumtii inferioare, indicatorii carry i overflow sunt teri, altfel sunt 1. IN - input byte and input word (input de octet i input de cuvnt) Indicatori afectai: nici unul Descriere: Coninutul acumulatorului este nlocuit de coninutul portului designat. Destinaia pentru input trebuie s fie AX sau AL, i trebuie specificat cu scopul comunicrii asamblorului a tipului intrrii. Numele portului trebuie s fie o valoare imediat ntre 0 i 255 sau numele registrului DX care trebuie umplut mai devreme cu locaia portului. INC - increment destination by one (incrementeaz destinaia cu unu) Indicatori afectai: AF,OF,PF,SF,ZF Descriere: Operandul specificat este adunat cu 1. Nu se genereaz carry. INT interrupt (ntrerupere) Indicatori afectai: IF,TF Descriere: Pointer-ul de stiv este decrementat cu 2 i indicatorii sunt salvai n stiv. Indicatorii de ntrerupere i capcan sunt pui la 0, din nou SP e decrementat 2 iar coninutul lui CS este salvat. CS este umplut cu partea semnificativ a vectorului de ntreruperi (dublucuvnt), deci cu segmentul de baz al rutinei de ntreruperi pentru acest tip de ntreruperi. SP e din nou decrementat cu doi, de data asta se salveaz IP n stiv. IP va fi umplut cu cuvntul mai puin semnificativ al vectorului de ntreruperi, locatat la adresa 24

absolut TYPE*4. Astfel se completeaz un apel intersegment la procedura care prelucreaz acest tip de ntrerupere (vezi de asemenea PUSHF, INTO, IRET). INTO - interrupt if overflow (ntrerupere dac exist overflow) Indicatori afectai: nici unul Descriere: Dac exista overflow pointer-ul de stiv este decrementat cu 2 i indicatorii sunt salvai n stiv. Indicatorii de ntrerupere i capcan sunt pui la 0, din nou SP e decrementat 2 iar coninutul lui CS este salvat. CS este umplut cu partea semnificativ a vectorului de ntreruperi (dublucuvnt), deci cu segmentul de baz al rutinei de ntreruperi pentru tipul 4 de ntreruperi. SP e din nou decrementat cu doi, de data asta se salveaz IP n stiv. IP va fi umplut cu cuvntul mai puin semnificativ al vectorului de ntreruperi, locatat la adresa absolut 16(10h). Astfel se completeaz un apel intersegment la procedura care prelucreaz acest tip de ntrerupere (vezi de asemenea INT, IRET, PUSHF). IRET - interrupt return (retur din ntrerupere) Indicatori afectai: toi Descriere: IP este nscris cu coninutul vrfului stivei. Ca urmare pointer-ul de stiva este incrementat cu 2, i cuvntul din capul stivei este introdus n CS. Astfel se ntoarce controlul n punctul n care a fost ntlnit ntreruperea. SP este din nou incrementat cu 2 i se refac indicatorii utiliznd cuvntul din vrful stivei. SP se incrementeaz din nou. JA/JNBE - jump if not below nor equal, or jump if above (salt dac nu e mai mic nici egal, sau salt la mai mare) Indicatori afectai: nici unul Descriere: Dac att indicatorul de carry ct i cel de zero sunt 0 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Daca CF sau ZF sunt 1 nu rezult nici un salt. JAE/JNB - jump if not below, or jump if above or equal(salt dac nu e mai mic sau salt dac e mai mare sau egal) Indicatori afectai: nici unul Descriere: Dac indicatorul de carry este 0 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac CF este 1 nu rezult nici un salt. JNAE/JB - jump if below, or jump if not above nor equal(salt daca e mai mic, sau salt daca nu e mai mare nici egal) JC - jump if carry(salt dac exist carry) Indicatori afectai: nici unul Descriere: Dac indicatorul de carry este 1 atunci distana de la sfritul acestei instruciuni pn la eticheta inta este adunat la IP, efectund un transfer. Dac CF este 0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNA/JBE - jump if below or equal, or jump if not above (salt dac e mai mic sau egal, sau salt dac nu e mai mare) Indicatori afectai: nici unul Descriere: Dac indicatorul de carry sau zero sunt 1 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac CF i ZF sunt 0 nu rezult nici un salt. 25

Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JCXZ - jump if CX is zero (salt daca CX este zero) Indicatori afectai: nici unul Descriere: Dac registrul numrator CX este 0 atunci distana de la sfritul acestei instruciuni pn la eticheta inta este adunat la IP, efectund un transfer. Dac CX este 1 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JE/JZ - jump if equal, jump if zero(salt daca e egal, salt la zero) Indicatori afectai: nici unul Descriere: Dac ultima operaie care a afectat indicatorul zero a dat un rezultat zero atunci (ZF) va fi 1. Dac (ZF)=1 atunci distana de sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac ZF este 0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octeti fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNLE/JG - jump if not less nor equal, or jump if greater (salt daca nu e mai mic sau egal, sau salt la mai mare) Indicatori afectai: nici unul Descriere : Dac indicatorul zero este 0 i indicatorii sign i overflow sunt egali atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac ZF este 1 sau (SF)<>(OF) nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNL/JGE - jump if not less, or jump if greater or equal (salt dac nu e mai mic, sau salt la mai mare sau egal) Indicatori afectai: nici unul Descriere: Dac indicatorii sign si overflow sunt egali atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (SF)<>(OF) nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JL/JNGE - jump on less, or jump on not greater nor equal (salt la mai mic, sau salt dac nu e mai mare sau egal) Indicatori afectai: nici unul Descriere: Dac indicatorii sign i overflow nu sunt egali (asta nseamn c (SF) sau-exclusiv cu (OF) este 1 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (SF)=(OF) nu rezult nici un salt. 26

Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JLE/JNG - jump if less or equal, or jump if not greater (salt daca e mai mic sau egal, sau salt dac nu e mai mare Indicatori afectai: nici unul Descriere: Dac indicatorii sign i overflow nu sunt egali (asta inseamna ca (SF) sau-exclusiv cu (OF) este 1 sau dac indicatorul zero e setat atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JMP - jump (salt) Indicatori afectai: niciunul Descriere: IP este nlocuit de offset-ul etichetei int n toate salturile intersegment, acelai lucru i pentru salturile indirecte n cadrul aceluiai segment. Dac este un salt direct n acelai segment atunci distana de la sfritul instruciunii pn la eticheta int e adunat la IP. Salturile inter-segment nlocuiesc prima data coninutul lui CS, utiliznd cuvntul urmtor instruciunii (direct) sau utiliznd cuvntul urmtor al adresei indicate (indirect). JNA/JBE - jump if below or equal, or jump if not above (salt daca e mai mic sau egal, sau salt dac nu e mai mare Indicatori afectai: nici unul Descriere: Dac indicatorul carry sau zero este setat atunci distana de la sfritul acestei instructiuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (CF)=0 i (ZF)=0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNAE/JB - jump if below, or jump if not above nor equal (salt dac e mai mic, sau salt dac nu e mai mare nici egal) Indicatori afectai: nici unul Descriere: Dac indicatorul carry este setat atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (CF)=0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNB/JAE - jump if not below, or jump if above or equal (salt daca nu e mai mic, sau salt dac e mai mare sau egal) JNC - jump if no carry (salt dac nu e carry) Indicatori afectai: nici unul Descriere: Dac indicatorul carry este zero atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (CF)=1 nu rezult nici un salt.

27

Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNBE - jump if not below nor equal (salt dac nu e mai mic nici egal) Indicatori afectai: nici unul Descriere: Dac nici indicatorul carry nici zero nu sunt setate atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (CF)=1 sau (ZF)=1 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNE/JNZ - jump if not equal, or jump if not zero (salt daca nu e egal, sau salt daca nu e zero) Indicatori afectai: nici unul Descriere: Dac indicatorul zero nu e setat atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (ZF)=1 nu rezult nici un salt. Observatie: Eticheta int trebuie sa fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNG/JLE - jump if not greater, or jump if less or equal (salt dac nu e mai mare, sau salt dac e mai mic sau egal) Indicatori afectai: nici unul Descriere: Dac indicatorul zero e setat, sau dac indicatorul sign nu e egal cu indicatorul overflow atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (ZF)=0 i (SF)=(OF) nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNGE/JL - jump if less, or jump if not greater nor equal (salt daca e mai mic, sau salt daca nu e mai mare sau egal) Indicatori afectai: nici unul Descriere: Dac indicatorul sign nu e egal cu indicatorul overflow atunci distana de la sfritul acestei instruciuni pna la eticheta int este adunat la IP, efectund un transfer. Dac (SF)=(OF) nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JGE/JNL - jump if not less, or jump if greater or equal (salt daca nu e mai mic, sau salt dac e mai mare sau egal) Indicatori afectai: nici unul Descriere: Dac indicatorul sign e egal cu indicatorul overflow atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (SF)<>(OF) nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. 28

JG/JNLE - jump if not less nor equal, or jump if greater (salt dac nu e mai mic nici egal, sau salt dac e mai mare) Indicatori afectai: nici unul Descriere: Dac indicatorul zero e resetat i indicatorul sign e egal cu indicatorul overflow atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (ZF)=1 sau (SF)<>(OF) nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. Comparaiile i deci implicit relaiile (mai mici, mai mari) se refer la dou valori fr semn. JNO - jump if not overflow (salt dac nu exist overflow) Indicatori afectai: nici unul Descriere: Dac indicatorul overflow este 0 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (OF)=1 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. JNS - jump on not sign, jump if positive (salt dac nu exista sign, salt dac e valoare pozitiv) Indicatori afectai: nici unul Descriere: Dac indicatorul sign este 0 atunci distana de la sfritul acestei instruciuni pna la eticheta int este adunat la IP, efectund un transfer. Dac (SF)=1 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. JNZ/JNE - jump on not zero, jump if not equal (salt dac nu exist zero, salt dac nu e egalitate) Indicatori afectai: nici unul Descriere: Dac indicatorul zero este 0 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (ZF)=1 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. JO - jump on overflow (salt dac exist overflow) Indicatori afectai: nici unul Descriere: Dac indicatorul overflow este 1 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (OF)=0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie in intervalul -128 la +127 octei fa de aceast instruciune. JP/JPE - jump on parity, or jump if parity even (salt dac exista parity, sau dac paritatea e par) Indicatori afectai: nici unul Descriere: Dac indicatorul parity este 1 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (PF)=0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. 29

JNP/JPO - jump on no parity, or jump if parity odd (salt dac nu exist parity, sau dac paritatea e impar) Indicatori afectai: nici unul Descriere: Dac indicatorul parity este 0 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (PF)=1 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. JS - jump on sign (salt dac exist sign) Indicatori afectai: nici unul Descriere: Dac indicatorul sign este 1 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (SF)=0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceasta instruciune. JZ/JE - jump if equal, jump if zero (salt dac exist egalitate, salt dac este zero) Indicatori afectai: nici unul Descriere: Dac indicatorul zero este 1 atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un transfer. Dac (ZF)=0 nu rezult nici un salt. Observaie: Eticheta int trebuie s fie n intervalul -128 la +127 octei fa de aceast instruciune. LAHF - load AH from flags (ncarc AH cu indicatorii de condiie) Indicatori afectai: nici unul Descriere: Biii registrului AH sunt umplui dup cum urmeaz: indicatorul sign umple bitul 7; indicatorul zero bitul 6; indicatorul carry auxiliar bitul 4; indicatorul parity bitul 2; indicatorul carry bitul 0. Biii 1, 3 i 5 a lui AH rmn nedeterminai. LDS - load data segment (ncarc segmentul de date) Indicatori afectai: nici unul Descriere: 1) Coninutul registrului specificat este nlocuit de partea mai puin semnificativ a cuvntului adresat de operandul (de tip dublu cuvnt) al instruciunii. LEA - load effective address (ncarc adresa efectiv) Indicatori afectai: nici unul Descriere: Coninutul registrului specificat este nlocuit de offset-ul variabilei indicate sau a etichetei sau a expresiei de tip adres. LES - load extra-segment register (ncarc registrul de segment auxiliar) Indicatori afectai: nici unul Descriere: 1) Coninutul registrului specificat este nlocuit de partea mai puin semnificativ a cuvntului adresat de operandul (de tip dublu cuvnt) al instruciunii. (REG)=(EA) 2) Coninutul registrului ES este nlocuit de partea semnificativ a cuvntului adresat de operandul (de tip dublu cuvnt) al instruciunii. (ES)=(EA+2) LOCK Indicatori afectai: nici unul Descriere: Orice instruciune poate fi precedat de un octet special de tip "lock". El face ca procesorul s serveasc semnalul de "bus-lock" (magistral ocupat) 30

pe timpul de execuie al instruciunii. In sistemele cu procesoare multiple care folosesc n comun resursele este necesar s se asigure un mecanism de control al accesului la aceste resurse. Se presupune c hardware-ul extern, dup recepia acestui semnal va asigura accesul la magistrala pentru ali "masteri" n timpul perioadei de aseriune a lui "bus-lock". LODS - load byte or word string (ncarc ir de octei sau cuvinte) Indicatori afectai: nici unul Descriere: Octetul surs (sau cuvntul) este ncrcat in AL (sau AX). Indexul surs este incrementat cu 1 (sau 2 pentru iruri de cuvinte) dac indicatorul direction este 0; altfel SI e decrementat cu 1 (sau 2). LOOP - loop, or iterate instruction sequence until count complete (bucla, sau secventa de iterare a instruciunilor pn la epuizarea numrtorului) Indicatori afectai: nici unul Descriere: Registrul numrtor (CX) este decrementat cu 1. Dac noul CX nu e 0, atunci distana de la sfritul acestei instruciuni pn la eticheta inta este adunat la IP, efectund un salt. Dac CX=0 , nu apare nici un salt. LOOPE/LOOPZ - loop on equal, or loop on zero (bucla la egal, sau bucla la zero) Indicatori afectai: nici unul Descriere: Registrul numrtor (CX) este decrementat cu 1. Dac noul CX nu e 0 i indicatorul zero este 1, atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un salt. Dac CX=0 sau dac (ZF)=0 nu apare nici un salt. LOOPNE/LOOPNZ - loop on not equal, or loop on not zero (bucla la neegal, sau bucla la nezero) Indicatori afectai: nici unul Descriere: Registrul numrtor (CX) este decrementat cu 1. Dac noul CX nu e 0 i indicatorul zero este 0, atunci distana de la sfritul acestei instruciuni pn la eticheta int este adunat la IP, efectund un salt. Dac CX=0 sau dac (ZF)=1 nu apare nici un salt. MOV move (mut) Indicatori afectai: nici unul Descriere: Exista 7 tipuri distincte de instructiuni de transfer. Fiecare tip are utilizari multiple depinznd de tipul datelor de mutat i de locaia acestor date. TIP 1: n memorie de la acumulator TIP 2: n acumulator din memorie TIP 3: n registru de segment din operand de tip memorie/registru TIP 4: n registru/memorie din registru segment TIP 5: n registru din registru TIP 6: n registru din data imediat TIP 7: n memorie / registru din data imediat MOVS - move byte string or move word string (mut ir de octei sau mut ir de cuvinte) Indicatori afectai: nici unul Descriere: irul surs al carui offset se gsete n SI este ncrcat n locaia din segmentul auxiliar al crui offset este n DI. SI i DI sunt amndou incrementate, dac indicatorul direction este 0, sau amndou decrementate dac (DF)=1. Incrementul sau decrementul e 1 pentru iruri de octei i 2 pentru iruri de cuvinte. 31

NEG - negate, or form 2's complement (neag sau formeaz complementul fa de 2) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Operandul specificat este sczut din 0FFH pentru octei sau 0FFFFH pentru cuvinte. Se adaug 1 i rezultatul este memorat n operandul dat. NOP - no operation (nici o operaie) Indicatori afectati: nici unul Descriere: NOP nu determina nici o operaie dar ine 3 perioade de ceas. Urmtoarea instruciune din secven este apoi executat. NOT - not, or form 1's complement (nu, sau formeaz complementul fa de 1) Indicatori afectai: nici unul Descriere: Operandul specificat este sczut din 0FFH pentru octei sau 0FFFFH pentru cuvinte. Rezultatul este memorat n operandul dat. OR - or, inclusive (sau, inclusive) Indicatori afectai: CF,OF,PF,SF,ZF Descriere: Fiecare poziie de bit n operandul destinaie (stnga) devine 1, pn cnd att el ct i bitul corespunztor din operandul surs (dreapta) sunt 0. Indicatorii carry i overflow devin 0. OUT - output byte and output word (output de octet i output de cuvint) Indicatori afectai: nici unul Descriere: Coninutul portului designat este nlocuit de coninutul acumulatorului. POP - pop word off stack into destination (terge un cuvnt din stiv i pune-l n destinaie) Indicatori afectai: nici unul Descriere: POP transfer un cuvnt de la locaia din stiva adresat de SP la operandul destinaie i incrementeaza SP cu 2. POPF - pop flags off stack (reface indicatorii din stiva) Indicatori afectai: toi Descriere: Indicatorii = ((SP)+1:(SP)), (SP)=(SP)+2 Registrul de indicatori sunt umplui cu poziiile corespunztoare de bit din cuvntul din vrful stivei: overflow = bit 11, direction = bit 10, interrupt = bit 9, trap = bit 8, sign = bit 7, zero = bit 6, auxiliary carry = bit 4, parity = bit 2, carry = bit 0. SP este apoi incrementat cu 2. PUSH - push word onto stack (salveaz cuvnt n stiv) Indicatori afectai: nici unul Descriere: 1) pointerul de stiv este decrementat cu 2, (SP)=(SP)-2 2) coninutul destinatiei este pus n cuvntul din vrful stivei PUSHF - push flags on stack (salveaz indicatorii n stiv) Indicatori afectai: nici unul Descriere: SP este decrementat cu 2, apoi indicatorii nlocuiesc biii corespunztori ai cuvntului din vrful stivei (vezi POPF). (SP)=(SP)-2, ((SP)+1:(SP))=indicatorii RCL - rotate left through carry (rotete stnga cu carry) Indicatori afectai: CF,OF Descriere: Operandul specificat ca destinaie (stnga) e rotit la stnga mpreun cu carry de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Rotaia continu pn cnd COUNT=0. CF este pstrat i e rotit n 32

bitul 0 al destinaiei. Bitul cel mai semnificativ al destinaiei e rotit n CF. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. RCR - rotate right through carry (rotete dreapta cu carry) Indicatori afectai: CF,OF Descriere: Operandul specificat ca destinaie (stnga) e rotit la dreapta mpreun cu carry de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Rotaia continu pn cnd COUNT=0. CF este pstrat i e rotit n bitul cel mai semnificativ al destinaiei. Bitul 0 e rotit in CF. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. REP/REPZ/REPE/REPNZ - repeat string operation (repet operaiile pe iruri) Indicatori afectai: depind de operaiile pe ir realizate Descriere: Operaia pe ir specificat este realizat de un numr de ori, pn cnd CX devine 0. CX este decrementat cu 1 dup fiecare operaie. Operaiile de comparare i scanare a irurilor determin o ieire din bucla dac indicatorul zero nu e egal cu valoarea bitului 0 al acestui octet de instruciune. RET - return from procedure (ntoarcere din procedura) Indicatori afectai: nici unul Descriere: Pointerul de instruciune este nlocuit de cuvntul din vrful stivei. SP este incrementat cu 2. Pentru ntoarcerea din alt segment, registrul CS este nlocuit cu cuvntul acum n vrful stivei i SP este din nou incrementat cu 2. Dac s-a specificat o valoare imediat n instruciunea RET aceast valoare este adunat la SP. ROL - rotate left (rotete stnga) Indicatori afectai: CF,OF Descriere: Operandul specificat ca destinaie (stnga) e rotit la stnga mpreun cu carry de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Rotaia continu pn cnd COUNT=0. CF este pierdut. Bitul cel mai semnificativ al destinaiei e rotit n CF. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. ROR - rotate right (rotete dreapta) Indicatori afectai: CF,OF Descriere: Operandul specificat ca destinaie (stnga) e rotit la dreapta mpreun cu carry de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Rotaia continu pn cnd COUNT=0. CF este pierdut. Bitul cel mai puin semnificativ al destinaiei e rotit n CF. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. SAHF Indicatori afectai: AF,CF,PF,SF,ZF Descriere: Cei cinci indicatori specificai sunt nlocuii de biii specifici din AH. (SF)=bit 7, (ZF)=bit 6, (AF)=bit 4, (PF)=bit 2, (CF)=bit 0;(SF):(ZF):X:(AF):X:(PF):X:(CF)=(AH) 33

SHL/SAL - shift arithmetic left and shift logic left (mut la stnga aritmetic, i mut la stnga logic) Indicatori afectai: CF,OF,PF,SF,ZF Descriere: Operandul specificat ca destinaie (stnga) e deplasat la stnga de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Deplasarea continu pn cnd COUNT=0. CF este pierdut. Bitul cel mai semnificativ al destinaiei e deplasat n CF. Bitul cel mai puin semnificativ e umplut cu 0. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. SAR - shift arithmetic right (mut la dreapta aritmetic) Indicatori afectai: CF,OF,PF,SF,ZF Descriere: Operandul specificat ca destinaie (stnga) e deplasat la dreapta de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Deplasarea continu pn cnd COUNT=0. CF este pierdut. Bitul cel mai puin semnificativ al destinaiei e deplasat n CF. Bitul cel semificativ e umplut cu 0. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. SBB - subtract with borrow (scade cu mprumut) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Operandul surs este sczut din operandul destinaie (stnga). Dac indicatorul carry era setat, se scade unu din rezultatul de mai sus. Rezultatul nlocuiete operandul destinaie original. SCAS - scan byte string or scan word string (scaneaz iruri de octei sau scaneaz iruri de cuvinte) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Elementul de ir specificat de DI n segmentul ES este sczut din valoarea existent n acumulator, operaia afectnd numai indicatorii. DI este incrementat (dac indicatorul direction este zero) sau decrementat (dac (DF)=1) cu 1 pentru octet sau 2 pentru cuvinte. SHR - shift logic right (mut la dreapta logic) Indicatori afectai: CF,OF,PF,SF,ZF Descriere: Operandul specificat ca destinaie (stnga) e deplasat la dreapta de un numr de ori (COUNT). Acest numr este sau exact 1, specificat de numrul absolut 1, sau este numrul inut n registrul CL, specificat explicit ca operand. Deplasarea continu pn cnd COUNT=0. CF este pierdut. Bitul cel mai puin semnificativ al destinaiei e deplasat n CF. Bitul cel mai semificativ e umplut cu 0. Dac COUNT=1 i cei doi bii mai semnificativi ai destinaiei au valori neegale atunci indicatorul overflow devine 1. Dac COUNT<>1, OF e nedefinit. STC - set carry flag (seteaz indicatorul carry) Indicatori afectai: CF Descriere: Indicatorul carry este setat la 1. STD - set direction flag (seteaz indicatorul direcie) Indicatori afectai: DF Descriere: Indicatorul direcie este setat la 1. 34

STI - set interrupt flag (seteaz indicatorul ntrerupere) Indicatori afectai: IF Descriere: Indicatorul ntrerupere este setat la 1. STOS - store byte string or store word string (memoreaz ir de octei sau ir de cuvinte) Indicatori afectai: nici unul Descriere: Octetul (sau cuvntul) din AL (sau AX) nlocuiete coninutul octetului sau cuvntului adresat de DI n ES. Apoi DI este incrementat dac indicatorul direction este 0 sau decrementat dac DF=1. Se va schimba valoarea cu 1 pentru octei i 2 pentru cuvinte. SUB - subtract (scadere) Indicatori afectai: AF,CF,OF,PF,SF,ZF Descriere: Operandul surs este sczut din operandul destinaie (stnga). Rezultatul nlocuiete operandul destinaie original. TEST - test, or logical compare (testeaz, sau compar logic) Indicatori afectai: CF,OF,PF,SF,ZF Descriere: Cei doi operanzi sunt supusi unui "i" logic pentru a afecta indicatorii dar nici unul din operanzi nu este afectat. Indicatorii carry i overflow devin 0. WAIT wait (ateapt) Indicatori afectai: nici unul Descriere: Nu se efectueaz nici o operaie. WAIT determin intrarea procesorului n starea wait dac pinul TEST nu e asignat. Starea WAIT poate fi ntrerupt de o ntrerupere extern. Cnd aceasta se ntmpl locaia de cod salvat e aceea a instruciunii WAIT, astfel nct dup ntoarcerea din ntrerupere se revine n starea wait. Starea wait este prsit cnd se furnizeaz semnalul TEST. Se reia astfel execuia i nu se permit ntreruperi pn cnd nu se intr n execuia instruciunii urmtoare. Instruciunea permite astfel procesorului s se sincronizeze cu hardware extern. XCHG exchange (schimb) Indicatori afectai: nici unul Descriere: Exist dou forme pentru instruciunea XCHG, una pentru comutarea coninuturilor acumulatorului cu acela al altor registre generale, i una pentru comutarea registrelor cu un operand de tip registru sau memorie. 1) Coninutul destinaiei e memorat temporar ntr-un registru intern de lucru (temp)=DEST ; 2) Coninutul destinaiei e nlocuit de coninutul operandului (DEST)=(SRC) 3) Coninutul anterior al destinaiei este mutat din registrul de lucru n operandul surs (SRC)=(temp) XLAT translate (translateaz) Indicatori afectai: nici unul Descriere: Coninutul acumulatorului este nlocuit de octetul din tabela. Adresa de nceput a tabelei a fost mutat n registrul BX. Coninutul original a lui AL este numrul de octei de dup adresa de start, unde trebuie gsit octetul dorit a fi translatat. El nlocuiete coninutul lui AL. XOR - exclusive or (sau exclusiv) Indicatori afectati: CF,OF,PF,SF,ZF Descriere: Fiecare poziie de bit n operandul destinaie (stnga) devine 0, dac poziiile corespunztoare din ambii operanzi sunt egale. Dac sunt neegale atunci aceea poziie de bit devine 1. Indicatorii carry i overflow devin 0. 35

2.3.

Extinderea structurii unitii centrale la familia 80x86

2.3.1. Unitatea central 80x86 din punct de vedere al programatorului Se vor discuta n acest capitol procesoarele reale 8088/8086, 80188/80186, 80286, i 80386/80486/80586/Pentium. Dintre componentele hardware ale sistemului de calcul cea mai important rmne unitatea central din punct de vedere al programrii n limbaj de asamblare. Cele mai utilizate componente ale unitii centrale sunt registrele i acestea au o importan deosebit n programarea n limbaj de asamblare. Vom prezenta n continuare, pe larg, modul de utilizare a registrelor unitii centrale. Fiecare procesor din familia 80x86 conine un set de registre. Particularitatea acestei familii de procesoare este reprezentat de faptul c un procesor conine un superset de regitrii ai procesorului precedent. Punctul de plecare l reprezint setul de registre al unitilor centrale ale procesoarelor 8088, 8086, 80188 i 80186 deoarece cele patru tipuri de procesoare au acelai tip de registre. n cele prezentate n continuare termenul de 8086 se va referi de fapt la oricare dintre aceste procesoare. Fabricantul acestor procesoare, firma INTEL, mparte registrele unitii centrale ale procesorului 8086 n trei categorii: o registre de uz general, o registre de segment, o registre cu destinaie special. Registrele de uz general sunt cele care pot aprea ca operanzi n operaiile aritmatice, logice i n instruciunile legate de acestea. Dei aceste registre sunt denumite de uz general, fiecare dintre ele se utilizeaz ntr-un anumit scop implicit dar destinaia acestora poate fi schimbat explicit de programator. Registrele segment sunt utilizate pentru accesarea unor blocuri de memorie numite segmente. Registrele de uz special au destinaii diverse. Dintre acestea, dou prezint o importan deosebit i vor fi prezentate pe scurt n continuare. 2.3.2. Registrele de uz general ale unitii centrale 8086 Unitatea central a procesorului 8086 are opt registre de uz general, de cte 16 bii fiecare, notate: ax, bx, cx, dx, si, di, bp i sp. Dei n calcule se pot folosi oricare din aceste registre, multe instruciuni lucreaz mai eficient iar altele chiar impun utilizarea unui anumit registru. Din acest motiv, denumirea de uz general dat acestor registre nu este chiar potrivit. Registrul ax (registrul Acumulator) este registrul n care au loc majoritatea calculelor aritmetice i logice. Dei operaiile aritmetice i logice pot fi efectuate i cu ajutorul altor registre, cel mai eficient este s se foloseasc registrul ax. Registrul bx (registrul Baz) are i el o destinaie special. Acest registru este folosit pentru a stoca adresa indirect (la acest procesor mai mult ca la procesoarele din familia x86). Registrul cx (registrul Contor) este utilizat de regul pentru contorizri la bucle sau pentru a stoca dimensiunea irurilor. 36

Registrul dx (registrul Date) are n general dou destinaii: el stocheaz depirile pentru anumite operaii aritmetice sau stocheaz adresa portului I/O la accesarea perifericelor. Registrele si i di (registrul Index Surs i registrul Index Destinaie) au de asemenea mai multe destinaii speciale. Registrele pot fi folosite ca pointer (indicator) la adresarea indirect a memoriei (similar cu registrul bx) sau pot fi folosite n operaiile pe iruri. Registrul bp (registrul Pointerul Indicatorul - Bazei) este similar registrului bx. El va fi n general utilizat pentru accesarea parametrilor i a variabilelor locale dintr-o procedur. Registrul sp (registrul Pointer (Indicator) Stiv) are o destinaie foarte important: el pstreaz stiva programului. n mod normal acest registru nu trebuie folosit de programator pentru calcule aritmetice. Funcionarea corect a celor mai multe programe depinde n mod esenial de utilizarea corect a acestui registru. Primele patru registre ax,bx,cx i dx ale unitii centrale 8086 pot fi folosite de asemenea ca registre pe opt bii. Aceste registre sunt denumite: al, ah, bl, bh, cl, ch, dl i dh. Denumirile se refer la partea superioar sau inferioar a registrelor pe 16 bii aa cum este prezentat n figura urmtoare.

Este de notat faptul c registrele pe 8 bii nu sunt registre independente. O modificare n registrul al, de exemplu, va modifica i registrul ax; la fel i dac va fi modificat registrul ah. Este evident c i modificarea registrului ax va duce la modificarea registrelor ah i al. Este de asemenea de remarcat faptul c modificarea registrului al nu va afecta registrul ah i invers. Registrele si, di, bp i sp sunt registre numai pe 16 bii. 2.3.3. Registrele de segment 8086 Procesorul 8086 are patru registre de segment: cs, ds, es i ss. Numele lor sunt respectiv: registrul segment de cod (Code Segment), registrul segment de date (Data Segment), registrul segment de date suplimentar (Extra Segment) i registrul segment de stiv (Stack Segment). Toate aceste registre au dimensiunea de 16 bii i ele permit selectarea blocurilor (segmentelor) din memoria principal. Un registru segment indic (conine) adresa de nceput a unui segment de memorie. Segmentul de memorie la 8086 nu poate avea o dimensiune mai mare de 65536 octei, adic are maximum 64 de Koctei. Registrul cs indic segmentul de memorie ce conine instruciunile main ce sunt executate la un moment dat. Dei un segment are dimensiunea unui segment este 37

de maximum 64 Koctei, programele pot avea dimensiuni mai mari de 64 de Koctei. Acest lucru se realizeaz prin folosirea mai multor segmente i comutarea ntre aceste segmente prin schimbarea coninutului registrului cs. Registrul ds indic n general segmentul ce conine datele globale ale programului. i aici putem face aceeai observaie, faptul c datele unui program nu trebuie s se limiteze la maximum 64 de Koctei. Registrul es indic un segment suplimentar numit extrasegment. Programele scrise pentru 8086 folosesc adesea acest registru pentru a avea acces la alte segmente atunci cnd este dificil sau imposibil s se modifice alte registre segment. Registrul ss indic segmentul unde se afl stiva 8086. Stiva reprezint locul unde 8086 stocheaz informaii importante cu privire la starea mainii, adresele de rentoarcere din subprograme, parametrii procedurilor i variabile locale. n general coninutul registrului segment de stiv nu trebuie modificat din cauz ca multe date importante ale sistemului depind de acesta. De asemenea este posibil s se stocheze date n segmentul de stiv dar acest lucru nu trebuie fcut niciodat deoarece coninutul stivei reprezint indicatoare la zone de memorie accesibil i o ncercare de a folosi stiva n alte scopuri poate crea probleme considerabile n special cnd folosii uniti centrale mai evoluate cum este, spre exemplu, 80386. 2.3.4. Registrele de uz special Unitatea central a procesorului 8086 are dou registre cu destinaie special: contorul de program ip (instruction pointer) i registrul bistabililor de condiii. Aceste registre nu pot fi accesate n acelai fel cu celelalte registre ale unitii centrale 8086. De regul unitatea central controleaz n mod direct aceste registre. Registrul ip este echivalent cu registrul ip al procesoarelor x86 el conine adresa instruciunii curente n execuie. Registrul ip este un registru pe 16 bii care indic adresa din segmentul de cod curent (cu 16 bii pot fi selectate 65536 de locaii de memorie diferite). Registrul bistabililor de condiii (sau a fanioanelor de condiii) este diferit de celelalte registre ale unitii centrale 8086 care pot memora valor de 8 sau 16 bii. Registrul bistabililor de condiii este de fapt o colecie de bistabile, fiecare dintre acestea ajutnd la determinarea strii curente a procesorului. Dei registrul bistabililor de condiii are o dimensiune de 16 bii, 8086 nu folosete dect nou dintre acetia. Patru fanioane sunt folosite n mod frecvent la programare: zero, carry, sign i overflow. Aceste fanioane mai sunt denumite i coduri de condiii. Registrul bistabililor de condiii este prezentat mai jos.

38

2.3.5. Registrele 80286 La 80286 apar modificri consistente la componentele vizibile programatorului n modul protejat. Totui nu vom discuta aici despre modul protejat la 80286 pentru c acest mod este folosit doar n cazuri speciale. Cu toate acestea se vor prezenta registrele suplimentare i bistabilii de stare ce apar n plus n caz c v vei ntlni cu acetia. n registrul bistabililor de condiii la 80286 apar trei bistabili suplimentari. Nivelul privilegiat pentru operaii I/O are doi bii (biii 12 i 13) i specific unul din cele patru nivele de privilegii posibile pentru realizarea operaiilor I/O. Aceti doi bii conin n general valoarea 00b cnd 80286 lucreaz n modul real (modul 8086 emulat). Bistabilul NT (nested task) controleaz operaiile realizate de instruciune de rentoarcere din ntrerupere (IRET). n mod normal NT este zero n programele ce lucreaz n modul real. n afar de biii suplimentari din registrul bistabililor de condiii, 80286 mai are cinci registre suplimentare folosite de sistemul de operare pentru gestionarea memoriei i a mai multor procese: the machine status word (msw), the global descriptor table register (gdtr), the local descriptor table register (ldtr), the interrupt descriptor table register (idtr) and the task register (tr). n modul protejat la procesorul 80286 poate fi accesat o memorie mai mare de un megaoctet. Datorit faptului c procesorul este depit aceast metod este rareori folosit de programatori. 2.3.6. Registrele procesoarelor 80386/80486 La procesorul 80386 a fost extins n mod semnificativ setul de registre. Acesta conine toate registrele procesorului 80286 (i implicit 8086) dar are cteva registre suplimentare i definirea registrelor existente a fost extins. Procesorul 80486 nu are registre suplimentare fa de 80386 dar are definii civa bii rmai nedefinii la 80386. Cea mai important schimbare din punct de vedere al programatorului la procesorul 80386 a fost introducerea setului de registre de 32 de bii. Registrele ax, bx, cx, dx, si, di, bp, sp, registrul bistabililor de condiii i ip sunt extinse la 32 de bii. La 80386 aceste registre se numesc eax, ebx, ecx, edx, esi, edi, ebp, esp, eflags, i eip pentru a le diferenia de varianta de 16 bii (care sunt i ele disponibile la 80386). Pe lng registrele de 32 de bii 80386 are de asemenea dou registre segment noi de 16 bii numite fs i gs care permit programatorului s acceseze simultan ase segmente de memorie diferite fr a fi necesar rencrcarea registrelor segment. Trebuie fcut observaia c la 80386 registrele de segment au rmas toate pe 16 bii. n registrul bistabililor de condiii nu s-a fcut nici o modificare dar acesta a fost extins la 32 de bii (eflag) i au fost definii biii 16 i 17. Bitul 16 este fanionul de ncepere a depanrii (RF) utilizat de registrele de depanare ale lui 80386. Bitul 17 este fanionul pentru modul virtual (VM) care semnaleaz dac procesorul lucreaz n modul virtual 86 (care simuleaz un procesor 8086) sau n modul protejat standard. Procesorul 80486 adaug un al treilea bit n registrul eflags pe poziia 18, fanionul de verificare a alinierii. mpreun cu registrul de control zero (CR0) din 80486, acest fanion foreaz o ntrerupere (abandon program) atunci cnd procesorul acceseaz o dat nealiniat (de exemplu, un cuvnt de la o adres impar sau un dublu cuvnt de la o adres care nu este multiplu de patru). 39

Procesorul 80386 are suplimentar patru registre de control CR0-CR3. Aceste registre constituie o extensie a registrului msw a lui 80286 (80386 emuleaz registrul msw a lui 80286 pentru compatibilitate dar informaiile apar n realitate n registrele CRx). La 80386 i 80486 aceste registre controleaz funcii cum ar fi gestionarea memoriei paginate, operaii de activare/dezactivare a memoriei cache (numai la 80486), operarea n mod protejat i altele. Procesoarele 80386/486 au de asemenea opt registre de depanare suplimentare. Un program de depanare cum sunt Microsoft Codeview sau Turbo Debugger poate utiliza aceste registre pentru a seta puncte de ntrerupere cnd se ncearc localizarea unei erori ntr-un program. Dei aceste registre nu sunt utilizate n programe ele sunt foarte utile n depanatoare pentru gsirea i eliminarea rapid a erorilor. n sfrit, procesoarele 80386/486 au suplimentar o serie de registre de test care testeaz funcionarea corect a procesorului cnd sistemul este pornit. Cel mai probabil Intel a pus aceste registre pentru testarea imediat dup fabricaie dar proiectanii de sistem pot folosi avantajul oferit de aceste registre la testul power-on. Pentru marea majoritate a programatorilor n limbaj de asamblare registrele suplimentare aprute la procesoarele 80386/486/Pentium nu prezint o prea mare importan. Oricum, extensia la 32 de bii i registrele extrasegment sunt destul de folositoare. Pentru programatorii de aplicaii, modelul de programare pentru procesoarele 80386/486/Pentium este cel prezentat n figura urmtoare.

2.3.7. Organizarea memoriei fizice la 80x86 ntr-un sistem de calcul Von Neumann unitatea central este conectat la memorie prin intermediul unei magistrale. Procesorul 80x86 selecteaz un anumit element de memorie prin trimiterea unui valori binare pe magistrala de adrese. Din alt punct de vedere memoria reprezint o matrice de octei. O structur de date n Pascal care este similar unei memorii va fi: Memory : array [0..MaxRAM] of byte; Valoarea de pe magistrala de adrese corespunde indexului furnizat acestei matrice. De exemplu, scrierea unei date n memorie este echivalent cu: Memory[address] := Value_to_write; 40

Citirea unei date din memorie este echivalent cu: Value_read := Memory[address]; n funcie de tipul unitii centrale numrul maxim de locaii de memorie (spaiul maxim de adresare ) este diferit. De exemplu, 80386 are o magistral cu 32 de linii de adres ceea ce nseamn c poate adresa pn la patru gigaoctei de memorie. De asemenea, nu este obligatoriu ca ntreg spaiul maxim de adresare s fie acoperit cu memorie fizic existent n sistem. Primul megabit de memorie, de la adresa zero la 0FFFFFh este special pentru 80x86. Acesta corespunde spaiului maxim adresabil la procesoarele 8088, 80186 i 80188. Cele mai multe programe DOS limiteaz dimensiunea codului i a datelor la acest domeniu. Adresele limitate la acest domeniu se numesc adrese reale dup modul real 80x86. 2.3.8. Segmentele la 80x86 Pentru a putea nelege adresarea memoriei la procesoarele 80x86 trebuie discutat mai ni mecanismul segmentrii. Mecanismul segmentrii furnizeaz un mecanism puternic de gestionare a memoriei. Acesta permite programatorilor s partiioneze programele n module care pot opera independent unul de cellalt. Segmentele furnizeaz de asemenea o cale de implementare simpl a programelor orietate pe obiecte. O alt facilitate a segmentrii este aceea c permite simplificarea utilizrii n comun a datelor de ctre dou procesoare. n concluzie segmentarea este o facilitate puternic care poate ridica ns unele probleme la realizarea programelor. Principalele probleme de care trebuie inut cont la utilizarea segmentrii sunt sistemul de operare utilizat i tipul de procesor. Dac sistemul de operare DOS impune o anumit limit i procesoarele care pot face adresarea pe 16 sau 32 de bii ridic unele probleme. Dac vom considera memoria ca un vector liniar atunci adresarea poate fi fcut prin furnizarea adresei (indexului) curente n spaiul maxim de adresare. Acest mod de adresare se numete adresare liniar. Adresarea segmentat necesit dou componente pentru a specifica o locaie de memorie: o valoare de segment i o valoare a ofsetului n segmentul respectiv. Ideal ar fi ca cele dou valori s fie independente una de cealalt. Cel mai simplu mod de a descrie adresarea segmentat este s considerm o matrice bidimensional. Valoarea segmentului furnizeaz un indice iar ofsetul cellalt indice din matrice, conform figurii urmtoare.

Adresarea memoriei prin specificarea segmentului Y i a offsetului X

41

S explicm care este avantajul unei astfel de structuri. S presupunem c se scrie un program n care este necesar o rutin care s calculeze funcia SIN(X). Vor fi necesare o serie de variabile temporare care cel mai probabil nu vor fi folosite ca variabile global ci ca variabile locale n interiorul rutinei de calcul a funcieiSIN(X). n sens larg aceasta este una din facilitile oferite de segmentare: s poat fi ataate blocuri de variabile (un segment) la o anumit seciune de cod. Dac programul creat conine un segment pentru variabilele locale ale funciei SIN, un segment pentru variabilele locale ale funciei SQRT, este imposibil ca rutina SIN s afecteze datele din segmentul de variabile SQRT aa cum s-ar putea ntmpla la adresarea liniar. ntradevr, cu procesorul 80286 i urmtoarele lucrnd n modul protejat, unitatea central poate ca o rutin s modifice accidental variabilele dintr-un segment diferit. O adres complet atunci cnd se folosete adresarea segmentat se compune din adresa de segment i adresa ofsetului (deplasamentului). O astfel de adres se scrie: segment:offset. La procesoarele 8086 pn la 80286 aceste dou valori sunt constante pe 16 bii. ncepnd cu procesorul 80386 ofsetul poate fi o constant pe 16 sau 32 de bii. Dimensiunea ofsetului limiteaz valoarea maxim a unui segment. La procesorul 8086 cu un ofset pe 16 bii, segmentul poate avea cel mult 64K (un segment poate fi mai mic dect valoarea sa maxim dar niciodat mai mare). La procesoarele 80386 i urmtoarele, ofsetul avnd 32 de bii rezult c segmentele pot avea dimensiuni maxime de patru gigaoctei. Dimensiunea segmentului este de 16 bii la toate procesoarele 80x86 i deci un singur program poate avea pn la 65536 de segmente diferite. Majoritatea programelor au ins n jur de 16 segmente dar acest numr nu reprezint o limit. Bineneles c, n ciuda faptului c familia procesoarelor 80x86 folosete adresarea segmentat, memoria fizic conectat la unitatea central este o arie liniar de octei. Unitatea central are funcia de a transforma valoarea furnizat de adresarea segmentat (numit i adresare logic) n valoarea adresei reale (adresare fizic). La procesoarele 8086, 8088, 80186 i 80188 (i celelalte procesoare care lucreaz n modul real), funcia de conversie de la adresa logic (de segment) la cea fizic (real) este foarte simpl. Unitatea central nmulete cu 16 (10h) valoarea coninut de registrul segment i o adun cu valoarea ofsetului. De exemplu dac vom considera adresa logic: 1000:1F00. Pentru calculul adresei fizice se nmulete valoarea 1000h cu 10h (16 n baza 10). nmulirea n hexazecimal se face extrem de simplu prin adugarea cifrei zero la denmulit: 1000h x 10h = 10000h. La valoarea obinut se adun ofsetul i se obine: 10000h + 1F00h ----------11F00h Valoarea 11F00h este cea corespunztoare adresei fizice (reale, din cauz c memoria este un vector liniar), adic 73472 n baza zece. Din acest mod de calcul este evident c pentru o adres fizic pot fi mai multe adrese logice n funcie de cum se alege adresa de segment i cea a ofsetului. De exemplu aceeai adres fizic se obine pentru adresa logic: 1100:0F00. Firma Intel, atunci cnd a proiectat procesoarele 80286 i urmtoarele, nu a extins adresarea prin adugarea unor bii suplimentari la registrele de segment. n 42

schimb a fost schimbat funcia prin care unitatea central calculeaz adresa fizic. Dac scriei programe bazate pe calculul adresei fizice prin nmulirea cu 16 a adresei de segment i adunarea ofsetului, aceste programe vor funciona numai pe procesoare 80x86 care funcioneaz n modul real i nu vei avea acces dect la cel mult un megaoctet de memorie (aceeai limitare apare dac vei lucra n modul virtual 86 V86 la procesoarele 80386 sau urmtoarele). La procesoarele 80286 i urmtoarele firma Intel a introdus segmentele n mod protejat. Printre alte schimbri, firma Intel a schimbat complet algoritmul de calcul a adresei fizice pe baza adresei logice. n loc s utilizeze un algoritm, ca cel prezentat mai sus, procesoarele n modul protejat folosesc un tabel de cutare (tabela descriptoare de segment) pentru a calcula adresa fizic. n modul protejat, procesorul 80286 i urmtoarele folosesc valoarea din adresa de segment ca index ntr-o matrice. Coninutul elementului din matrice furnizeaz (printre altele) adresa de nceput a segmentului. Unitatea central va aduna aceast valoare la valoarea ofsetului pentru a obine valoarea adresei fizice. Modul de obinere a adresei fizice este ilustrat n figura urmtoare.

Adresa de segment se folosete ca index ntr-o tabel descriptoare de segment. Valoarea extras de la aceast locaie este adunat cu ofsetul pentru a obine adresa fizic

Trebuie reinut faptul c aplicaiile create de programator nu pot modifica direct tabela descriptoare de segment (tabela de cutare). Sistemele de operare n mod protejat (UNIX, Linux, Windows, OS/2 etc.) dirijeaz aceast operaie. 2.3.9. Adrese normalizate la 80x86 Cnd se opereaz n modul real, apare o problem interesant (cea amintit anterior). Ne putem referi la un singur obiect din memorie folosind adrese diferite. Dac relum exemplul anterior, adresa 1000:1F00, putem construi i alte adrese logice care s se refere la aceeai adres fizic. De exemplu: 11F0:0, 1100:F00 i chiar 1080:1700 corespund toate aceleiai adrese fizice i anume 11F00h. Cnd se lucreaz cu mai multe tipuri de date i n special atunci cnd se compar pointerii este convenabil ca atunci cnd adresele de segment indic obiecte diferite din memorie ca valoarea registrului de segment s fie reprezentat diferit. Este limpede c aceasta nu este ntotdeauna cazul procesoarelor 80x86 lucrnd n modul real. 43

Din fericire exist o cale simpl de a rezolva problema. Dac este necesar s se compare dou adrese se pot folosi adrese normalizate. Adresele normalizate au o form special i aceasta este ntotdeauna unic. Acest lucru se ntmpl n afar de cazul cnd dou valori ale segmentelor normalizate sunt identice i ele nu se refer la acelai obiect din memorie. Sunt mai multe ci diferite (de fapt 16) pentru a crea adrese normalizate. Prin convenie, cei mai muli programatori (chiar i de limbaje de nivel nalt) definesc o adres normalizat astfel: o adresa de segment poate fi orice valoare pe 16 bii; o ofsetul trebuie s fie o valoare cuprins n domeniul: 0 ... 0Fh. Pointerii normalizai n felul acesta sunt foarte uor de convertit la adresa fizic. Singurul lucru pe care-l avei de fcut este s adugai singura cifr hexazecimal a ofsetului la sfritul valorii segmentului. Forma normalizat a adresei 1000:1F00 este 11F0:0. Adresa fizic se obine foarte uor adugnd la sfritul adresei de segment 11F0, valoarea 0 a ofsetului, obinnd: 11F00. Este foarte uor de a converti o valoare oarecare a unei adrese de segmentate ntr-o valoare normalizat. Mai nti se convertete adresa segmentat la adresa fizic prin nmulirea cu 16 a valorii adresei de segment i apoi adunarea la aceasta a valorii ofsetului. Introducei apoi simbolul dou puncete : ntre ultimile dou cifre a rezultatului care trebuie s aib cinci cifre: 1000:1F00 11F00 11F0:0 Este important de reinut c adresa normalizat se folosete doar la proacesoarele 80x86 ce opereaz n modul real. n modul protejat nu exist o coresponden direct ntre adresa segmentat i adresa fizic i deci tehnica descris nu poate fi folosit. Atunci cnd se vorbete de adrese normalizate se va subnelege c procesorul lucreaz n modul real. 2.3.10. Registrele de segment la procesoarele 80x86 Atunci cnd firma Intel a proiectat procesorul 8086, n anul 1976, memoria era o resurs preioas. Din acest motiv firma a proiectat setul de instruciuni n aa fel nct s se utilizeze ct mai puini bii pentru codificarea acestora. Acest lucru a dus la programe mai mici i n consecin calculatoarele dotate cu procesoare Intel necesitau mai puin memorie i erau mai ieftine. Odat cu scderea preului memoriei acest aspect aparent ar prea s devin neimportant. Rmne totui adevrat faptul c programele de dimensiuni mici (i implicit instruciunile scurte) vor fi executate mai repede de ctre unitatea central i asta va duce la creterea global a vitezei de execuie a programelor. n aceast idee, firma Intel a dorit evitarea scrierii adresei ntregi de 32 de bii (segment i ofset) n instruciunile ce fac referire la anumite zone de memorie. n mod curent instruciunile conin numai 16 bii ai adresei de ofset. Pentru a putea realiza acest lucru se fac anumite atribuiri implicite registrelor de segment n aa fel nct unitatea central, n funcie de context i de tipul instruciunii, s poat determina care anume din registrele de segment este folosit mpreun cu adresa de ofset. 44

Procesoarele 8086 pn la 80286 au patru registre de segment: cs, ds, es i ss. Procesoarele 80386 i urmtoarele au pe lng aceste registre de segment, nc dou registre de segment suplimentare: fs i gs. Registrul de segment cs indic segmentul ce conine codul ce se execut la un moment dat. Unitatea central va executa ntotdeauna instruciunile de la adresa cs:ip. De asemenea n mod implicit unitatea central va cuta variabilele aferente programului executat n segmentul de date. Alte variabile sau operaii se vor executa n segmentul de stiv. Cnd se acceseaz aceste zone specifice nu este necesar specificarea registrului de segment utilizat. Pentru accesarea datelor din extrasegmente (es, fs sau gs) este necesar un singur bit pentru a specifica registrul corespunztor. n setul de instruciuni al procesorului doar cteva instruciuni de transfer necesit necesit specificarea adresei segmentate n ntregime pe 32 de bii. Toate aceste lucruri pot prea nite limitri n utilizarea procesorului. De exemplu, cu ajutorul celor patru registre de segment ale procesorului 8086 nu se pot folosi la un moment dat dect 256 Kilooctei (64 Kilooctei maxim pentru fiecare segment) de memorie din totalul de un Megaoctet. Problema se rezolv prin modificarea coninutului registrelor de segment i n acest fel poate fi accesat toat memoria disponibil. Este evident faptul c instruciunile pentru schimbarea coninutului registrului de segment de la procesoarele 80x86 vor consuma memorie i un anumit timp pentru execuie. Cu toate acestea soluia de a folosi adresarea implicit (fr specificarea registrului de segment) rmne mai eficient deoarece pe parcursul unui program necesitatea schimbrii segmentului (pentru accesarea datelor din segmente diferite, de exemplu) este destul de puin frecvent.

2.4.

Modurile de adresare la procesoarele 80x86

Existena modurilor de adresare permite estimarea posibilitilor de programare n limbaj de asamblare a unei uniti centrale. Cu ct modurile de adresare a operanzilor (posibilitile de accesare a memoriei) sunt mai diversificate cu att posibilitile de programare sunt mai extinse i programele obinute mai performante. Procesoarele 80x86 permit accesarea memoriei prin mai multe ci diferite. Modurile de adresare ale procesoarelor 80x86 furnizeaz un mod flexibil de accesare a memoriei permind accesarea simpl a variabilelor, matricilor, nregistrrilor, pointerilor sau a altor tipuri de date complexe. Stpnirea modurilor de adresare al procesoarelor 80x86 este primul pas n nvarea programrii n limbaj de asamblare. Cnd firma Intel a proiectat procesorul 8086, l-a prevzut cu un set de moduri de adresare a memoriei flexibil dar limitat. La procesorul 80386 au fost adugate mai multe moduri de adresare dar trebuie reinut faptul c au fost pstrate toate modurile de adresare a procesoarelor anterioare din motive de compatibilitate. Dei modurile de adresare noi nu vor putea fi folosite pe procesoarele anterioare (cum ar fi 80286), nici evitarea acestor moduri noi de adresare nu este convenabil dac programul este scris pentru un procesor 80386 din cauz c se pierd faciliti importante ce fac programul mai performant. Din acest motiv, prezentarea se va face separat pentru cele dou seturi de moduri de adresare pentru evitarea confuziilor.

45

2.4.1. Modul de adresare a registrelor la procesorul 8086 Cele mai multe instruciuni ale procesorului 8086 pot opera cu registrele de uz general. Prin specificarea numelui registrului ca operand ntr-o instruciune se poate avea acces la coninutul acelui registru. S considerm instruciunea mov (move deplaseaz, mut): mov destinaie, surs

Aceast instruciune copie informaia din operandul surs n operandul destinaie. Registrele pe 16 sau 8 bii sunt operanzi valizi pentru aceast instruciune. Singura restricie este reprezentat de faptul c cei doi operanzi trebuie s aib aceeai dimensiune (8 sau 16 bii). Iat cteva exemple: mov mov mov mov mov mov ax, bx dl, al si, dx sp, bp dh, cl ax, ax ;Copie valoarea din BX n AX ;Copie valoarea din AL n DL ; Copie valoarea din SI n DX ; Copie valoarea din BP n SP ; Copie valoarea din CL n DH ;Aceasta instruciune este posibila dar nu modific nimic

Registrele reprezint locul cel mai convenabil n care s se pstreze variabilele mai des folosite. n acest fel se evit accesul repetat la memorie i viteza de execuie a programului crete iar instruciunile folosite vor fi mai scurte. n continuare se vor folosi prescurtrile pentru operanzi: reg i r/m (registru/memorie) ori de cte ori va fi vorba de unul din registrele de uz general ale procesorului 8086. n afar de registrele de uz general, multe instruciuni ale procesorului 8086 (inclusiv instruciunea mov) permit folosirea unui registru segment ca operand. Aici avem ns dou restricii: n primul rnd, registrul cs nu poate fi specificat ca operand destinaie i n al doilea rnd, doar unul singur dintre operanzi poate fi registru de segment. Asta nseamn c nu se poate transfera coninutul unui registru segment n altul cu o singur instruciune mov. Pentru a copia valoarea registrului cs n registrul ds se poate folosi o secven de felul urmtor: mov mov ax, cs ds, ax

Un registru segment nu trebuie folosit niciodat la stocarea datelor ntmpltoare. Aceste registre trebuie s conin doar adrese de segment. Pentru registre de segment se va folosi prescurtarea seg ori de cte ori un registru de segment este permis (sau necesar) ca operand. 2.4.2. Modurile de adresare ale memoriei la procesorul 8086 Procesorul 8086 furnizeaz 17 ci diferite de acces la memorie. Dei par destul de multe, din fericire cele mai multe moduri de adresare sunt variante ce deriv una din cealalt i din acest motiv sunt foarte uor de nvat. 46

Modurile de adresare posibile la familia de procesoare 8086 sunt: numai deplasament, baz, deplasament plus baz, deplasament plus index i deplasament plus baz plus index. Variaii ale acestor cinci forme furnizeaz cele 17 moduri de adresare diferite ale procesorului 8086. 2.4.2.1. Modul de adresare numai prin deplasament Cel mai utilizat mod de adresare i cel mai uor de neles este modul de adresare numai prin deplasament (sau direct). Modul de adresare direct const n specificarea unei valori constante pe 16 bii care care reprezint valoarea adresei locaiei adresate. Instruciunea: mov al, ds:[8088h]

ncarc registrul al cu valoarea coninut de locaia de memorie 8088h. De asemenea instruciunea: mov ds:[1234h],dl

stocheaz valoarea registrului dl n locaia de memorie 1234h.

NOT: Sintaxa MASM pentru modurile de adresare a memoriei. Asamblorul Microsoft MASM folosete diferite notaii pentru adresarea indexat, bazat/indexat i deplasament plus bazat/indexat. Urmtoarea list prezint combinaiile care sunt posibile la modurile de adresare 8086: disp[bx], [bx][disp], [bx+disp], [disp][bx] i [disp+bx] [bx][si], [bx+si], [si][bx] i [si+bx] disp[bx][si], disp[bx+si], [disp+bx+si], [disp+bx][si], disp[si][bx], [disp+si][bx], [disp+si+bx], [si+disp+bx], [bx+disp+si], etc. MASM trateaz simbolul [] la fel ca pe operatorul +. Acest operator este comutativ la fel ca operatorul +. Bineneles c acest discuie se refer la toate modurile de adresare pentru 8086 i nu numai cele care implic registrele bx i si. Aceste registre pot fi nlocuite cu oricare dintre registrele permis a fi utilizate n modurile de adresare descrise mai sus. 47

Modul de adresare numai prin deplasament (modul direct) este cel mai adecvat pentru accesarea variabilelor simple. Evident c este de preferat s se foloseasc nume ca I sau J n loc de DS:[1234h] sau DS:[8088h] pentru a simplifica lucrurile. Intel numete acest mod de adresare adresare numai prin deplasament deoarece se folosete o singur constant de 16 bii ce reprezint ofsetul (sau deplasamentul) n codul instruciunii mov. Din acest punct de vedere acest mod de adresare este foarte asemntor modului de adresare direct de la procesoarele x86 (vezi capitolul anterior). Exist ns cteva diferene minore. nainte de toate, deplasamentul reprezint o anumit distan dintre dou puncte. La adresarea direct de la procesoarele x86 acest lucru este adevrat considernd deplasamentul fa de adresa zero. La procesoarele 80x86 deplasamentul este de fapt ofsetul fa de nceputul segmentului (segmentul de date n exemplul nostru). Pentru moment considerm modul de adresare numai prin deplasament ca un mod de adresare direct. Trebuie reinut c la procesorul 8086 prin acest mod de adresare se pot accesa i cuvinte (word 2 octei) iar la 80386 cuvinte duble.

Implicit, toate valorile numai prin deplasament furnizeaz ofsetul n segmentul de date. Dac dorii s furnizai ofsetul ntr-un alt segment trebuie s punei simbolul segmentului (s prefixai adresa) nainte de adres. De exemplu, dac dorii s accesai locaia 1234h din extrasegment (es) trebuie s folosii instruciunea mov sub forma: es:[1234h] iar dac dorii s accesai locaia n segmentul de cod (cs): mov ax, cs:[1234h]. Apariia prefixului ds: n exemplele de la nceput nu reprezint o specificare a segmentului. Unitatea central utilizeaz segmentul de date (ds) implicit. n acele exemple a fost specificat ds: numai datorit limitrilor sintactice impuse de asamblorul MASM. 2.4.2.2. Modul de adresare indirect prin registre Unitile centrale ale procesoarelor 80x86 v permit adresarea indirect a memoriei prin intermediul registrelor folosind modul de adresare indirect prin registre. Sunt patru forme de adresare la 8086 cel mai bine exemplificate prin urmtoarele instruciuni: 48

mov al, [bx] mov al, [bp] mov al, [si] mov al, [di] La fel ca modul de adresare x86[bx], aceste patru moduri de adresare vor conine valoarea ofsetului n registrele bx, bp, si sau di. La utilizarea registrelor [bx], [si] i [di] registrul ds este registrul segment implicit iar pentru [bp] registrul de segment implicit este registrul de segment de stiv (ss). Se poate utiliza de asemenea specificarea explicit a registrului de segment dac se dorete accesarea datelor ntr-un segment diferit de cel implicit. Iat cteva exemple: mov al, cs:[bx] mov al, ds:[bp] mov al, ss:[si] mov al, es:[di] Intel se refer la modurile de adresare [bx] i [bp] ca moduri de adresare bazate iar la registrele bx i bp ca registre baz (de fapt bp este notaia pentru base pointer indicatorul bazei). La fel, la modurile de adresare ce folosesc [si] si [di] se numesc moduri de adresare indexate (si nseamn source index index surs iar ds, destination index index destinaie). n orice caz aceste moduri de adresare sunt din punct de vedere funcional echivalente (lucreaz la fel dac vom nlocui simbolurile [si] sau [di] cu [bx]). Din acest motiv vom numi aceste moduri de adresare ca adresare indirect prin registre pentru a fi consecveni. Modul n care funcioneaz acest mod de adresare este ilustrat n figurile urmtoare.

49

2.4.2.3. Modurile de adresare indexate Adresarea indexat folosete urmtoarea sintax: mov al, disp[bx] mov al, disp[bp] mov al, disp[si] mov al, disp[di] Dac registrul bx conine 1000h, atunci instruciunea mov cl,20h[bx] va ncrca registrul cl cu coninutul locaiei de memorie ds:1020h. De asemenea, dac registrul bp conine valoarea 2020h, atunci instruciunea mov dh,1000h[bp] va ncrca registrul dh cu valoarea coninut de locaia de memorie de la adresa ss:3020. Ofsetul generat de acest mod de adresare este suma dintre o constant i coninutul registrului specificat. Modurile de adresare care implic registrele bx, si i di folosesc segmentul de date ca segment implicit iar utilizarea registrului bp nseamn c registrul de segment de stiv ss va fi registrul implicit. i la acest mod de adresare se poate specifica explicit registrul de segment: mov al, ss:disp[bx] mov al, es:disp[bp] mov al, cs:disp[si] mov al, ss:disp[di] Modul de adresare bazat indexat este ilustrat n figurile urmtoare.

n figura de mai sus putem folosi registrele si sau di n locul registrului bx pentru a obine modurile de adresare pentru [si+disp] sau [di+disp]. 50

(Comparaie ntre adresarea bazat i adresarea indexat: aici trebuie s ne amintim faptul c Intel numete instruciunile formate cu bx sau bp ca instruciuni bazate iar cele cu si i di ca indexate; din acest motiv apare o confuzie n denumirea modurilor de adresare care trebuie corectat n acest text.) Exist o diferen subtil ntre modurile de adresare bazat i indexat. Amndou modurile de adresare constau ntr-un deplasament adunat la coninutul unui registru. Diferena esenial dintre cele dou moduri de adresare const n valoarea relativ a deplasamentului i cea coninut de registru. n modul de adresare indexat constanta furnizeaz n mod tipic adresa unei structuri de date specifice iar registrul furnizeaz un ofset pentru aceast adres. n modul de adresare bazat, registrul conine adresa structurii de date iar deplasamentul constant furnizeaz un index pentru acest punct. Deoarece adunarea este comutativ cele dou moduri de a privi problema sunt echivalente. Totui, deoarece Intel permite unul sau doi octei pentru deplasament este mai raional s numeasc acest mod de adresare bazat. Totui, de obicei modul de adresare bazat va fi folosit mai mult ca mod de adresare indexat i prin urmare numele se schimb. 2.4.2.4. Modul de adresare indexat bazat Modul de adresare indexat bazat este o combinaie ntre adresarea indirect prin registre. Acest mod de adresare formeaz ofsetul prin adunarea coninutului unui registru baz (bx sau bp) i coninutul unui registru index (si sau di). Formele posibile pentru acest mod de adresare sunt: mov al, [bx][si] mov al, [bx][di] mov al, [bp][si] mov al, [bp][di] S presupunem c registrul bx conine valoarea 1000h i registrul si conine valoarea 880h. Atunci instruciunea: mov al,[bx][si] va ncrca registrul al cu coninutul locaiei de memorie de la adresa ds:1880h. i aici se fac aceleai precizri cu privire la registrele segment implicite. 2.4.2.5. Adresare indexat bazat plus deplasament Acest mod de adresare este o modificare a modului de adresare bazat/indexat prin adugarea unei constante pe 8 bii sau 16 bii. Instruciunile urmtoare reprezint un exemplu al acestui mod de adresare. mov al, disp[bx][si] mov al, disp[bx+di] mov al, [bp+si+disp] mov al, [bp][di][disp] 51

S presupunem c registrul bp conine 1000h, bx conine 2000h, si conine 120h i di conine 5; atunci instruciunea mov al,10h[bx+si] va ncrca registrul al cu coninutul locaiei de memorie de la adresa DS:2130; instruciunea mov ch,125h[bp+di] ncarc registrul ch cu coninutul locaiei de memorie de la adresa SS:112A i instruciunea mov bx,cs:2[bx][di] ncarc registrul bx cu coninutul locaiei de memorie de la adresa CS:2007.

52

2.4.2.6. Un mod simplu de a reine modurile de adresare a memoriei la procesorul 8086 Aa cum s-a artat, exist 17 moduri de adresare la procesorul 8086: disp, [bx], [bp], [si], [di], disp[bx], disp[bp], disp[si], disp[di], [bx][si], [bx][di], [bp][si], [bx][di], disp[bx][si], disp[bx][di], disp[bp][si] i disp[bp][di] fr a ine cont de diferitele variante sintactice posibile. Toate aceste forme pot fi memorate dac se cunoate care combinaii sunt valide. Considerm tabelul urmtor:

Tabelul pentru generarea modurilor valide de adresare la procesorul 8086 Dac alegei zero sau unul din oricre din termenii unei coloane i-l alturai cel puin unui termen din celelalte coloane, obinei un mod de adresare valid la 8086. Iat cteva exemple: alegei disp din prima coloan, nimic din coloana doi i [di] din coloana a treia, se obine: disp[di]; alegei disp, [bx] i [di] i se obine: disp[bx][di] srii coloana unu i doi i alegei [si] din coloana trei; se obine [si]; srii prima coloan, alegei [bx] apoi [di] i se obine: [bx][di].

De altfel dac luai un mod de adresare care nu poate fi construit cu tabelul de mai sus, atunci acesta nu este legal. De exemplu, modul de adresare disp[dx][si] nu este posibil deoarece [dx] nu exist n tabelul de mai sus. 2.4.2.7. Cteva comentarii finale asupra modurilor de adresare la procesorul 8086 Adresa efectiv este ofsetul final obinut prin calcule la un anumit mod de adresare. De exemplu, dac registrul bx conine 10h atunci adresa efectiv pentru 10h[bx] este 20h. Vom ntlni termenul de adres efectiv n majoritatea discuiilor despre modul de adresare la procesorul 8086. Este chiar o instruciune special: load effective addresss (lea) care calculeaz adresa efectiv. Nu toate modurile de adresare necesit acelai timp de execuie. De regul, cu ct modul de adresare este mai complex cu att timpul necesar execuiei instruciunii va fi mai mare. De asemenea, deplasamentul, cu excepia modului de adresare numai deplasament, poate fi un numr cu semn pe 8 sau 16 bii. Dac deplasamentul este pe 8 bii (un numr n domeniul 128 ... +127) instruciunea va fi scurt i deci mai rapid. Din acest motiv, la modurile de adresare, de regul se prefer scrierea valorilor mari n registre n aa fel nct deplasamentul s fie pe 8 bii. 53

Dac dup calculul adresei efective rezult o valoare mai mare ca 0FFFFh, unitatea central ignor depirea iar rezultatul va fi rotunjit la cei mai puin semnificativi 16 bii (wraps around back to zero). De exemplu, dac registrul bx conine valoarea 10h atunci instruciunea mov al,0FFFFh[bx] va ncrca registrul al cu coninutul locaiei de la adresa 0Fh (0FFFFh + 10h = 1000Fh). 2.4.3. Modurile de adresare a registrelor la 80386 Procesorul 80386 i urmtoarele furnizeaz registre pe 32 de bii. Cele 8 registre de uz general se numesc: eax, ebx, exc, edx, esi, edi, ebp i esp. Aceste registre pot fi folosite ca operanzi n numeroase instruciuni ale procesorului 80386. 2.4.3.1.Modurile de adresare a memoriei la 80386 Procesorul 80386 a generalizat modurile de adresare la registre. Dac 8086 permitea utilizarea numai a registrelor bx i bp ca registre de baz i numai a registrelor di i si ca registre index, procesorul 80386 permite ca aproape orice registru s fie folosit ca registru de baz sau index. De asemenea se introduce un mod nou de adresare: adresarea indexat scalat care simplific accesul la elementele unei matrici. 2.4.3.2.Modul de adresare indirect prin registre La procesorul 80386 poate fi folosit oricare din registrele de uz general pe 32 de bii atunci cnd se folosete modul de adresare indirect prin registre. Simbolurile [eax], [ebx], [ecx], [edx], [esi] i [edi] furnizeaz ofsetul pentru registrul segment de date ds considerat registru segment implicit. Simbolurile [ebp] i [esp] folosesc segmentul de stiv ca segment implicit. Atunci cnd se ruleaz programe n modul real pe 16 bii a lui 80386, ofsetul din registrele pe 32 de bii trebuie s fie n domeniul 0 ... 0FFFFh. Nu se pot folosi valori mai mari deci nu se pot accesa segmente mai mari de 64k (acest lucru este posibil n modul protejat). De asemenea nu se pot folosi numele pe 16 bii ale registrelor ci numai cele pe 32 de bii. n continuare se prezint exemple de instruciuni corecte: mov al, [eax] mov al, [ebx] mov al, [ecx] mov al, [edx] mov al, [esi] mov al, [edi] mov al, [ebp] ;Folosete registrul SS implicit. mov al, [esp] ; Folosete registrul SS implicit. 2.4.3.3.Modurile de adresare indexat, indexat/bazat i bazat/indexat/deplasament la procesorul 80386 Modul de adresare indexat (indirect prin registru plus deplasament) v permite s folosii un registru pe 32 de bii i o constant. Modul de adresare bazat/indexat v permite s folosii perechi de dou registre de 32 de bii. n sfrit modul de adresare 54

deplasament/bazat/indexat v permite s combinai o constant cu dou registre pe 32 de bii pentru a forma adresa efectiv. Trebuie reinut faptul c ofsetul produs de calculul adresei efective trebuie s rmn pe 16 bii atunci cnd se lucreaz n modul real. La 80386 termenii de registru de baz i registru index capt nelesuri noi. Cnd combinm dou registre pe 32 de bii ntr-un mod de adresare, primul registru este registrul baz iar al doilea este registru index. Acest lucru este adevrat dac ne referim la numele registrelor. Procesorul 80386 permite utilizarea aceluiai registru att ca registru de baz ct i ca registru index lucru ce uneori este folositor. Urmtoarele instruciuni prezint exemple reprezentative pentru diferite moduri de adresare de baz i indexate: mov al, disp[eax] ;Moduri de adresare mov al, [ebx+disp] ; indexate. mov al, [ecx][disp] mov al, disp[edx] mov al, disp[esi] mov al, disp[edi] mov al, disp[ebp] ; Folosete registrul SS implicit. mov al, disp[esp] ; Folosete registrul SS implicit. Urmtoarele instruciuni folosesc toate modul de adresare bazat+indexat. Primul registru din cel de-al doilea operand este registrul bazei iar cel de-al doilea este registrul index. Dac registrul bazei este esp sau ebp adresa efectiv este relativ le segmentul de stiv. De reinut faptul c alegerea registrului index nu afecteaz alegerea segmentului implicit. mov al, [eax][ebx] mov al, [ebx+ebx] mov al, [ecx][edx] mov al, [edx][ebp] mov al, [esi][edi] mov al, [edi][esi] mov al, [ebp+ebx] mov al, [esp][ecx] ;Moduri de adresare ;bazat+indexat. ;Folosete DS implicit. ; Folosete registrul SS implicit. ; Folosete registrul SS implicit.

Evident c se poate aduga deplasamentul la modurile de adresare prezentate mai sus pentru a obine modul de adresare bazat+indexat+deplasament. Urmtoarele exemple sunt reprezentative pentru acest mod de adresare: mov al, disp[eax][ebx] mov al, disp[ebx+ebx] mov al, [ecx+edx+disp] mov al, disp[edx+ebp] mov al, [esi][edi][disp] mov al, [edi][disp][esi] mov al, disp[ebp+ebx] mov al, [esp+ecx][disp] ;Modul de adresare ; bazat indexat. ;Folosete DS implicit. ;Folosete SS implicit. ;Folosete SS implicit. 55

Exist o restricie la 80386 legat de registrul esp: acest registru poate fi folosit ca registru de baz dar nu poate fi folosit ca registru index. 2.4.3.4.Modul de adresare scalat indexat la procesorul 80386 Modurile de adresare: indexat, bazat/indexat i bazat/indexat/deplasament descrise pn acum sunt cazuri particulare ale adresrii indexate scalate ale procesorului 80386. Aceste moduri de adresare sunt utile n particular pentru adresarea elementelor matricilor dei ele nu sunt destinate numai acestui scop. Aceste moduri v permit s multiplicai registrul index din modul de adresare cu unu, doi, patru sau opt. Sintaxa general a acestui mod de adresare este: disp[index*n] [base][index*n] sau disp[base][index*n] unde baz sau index reprezint oricare din registrele pe 32 de bii ale procesorului 80386 iar n este un numr egal cu unu, doi, patru sau opt. 80386 calculeaz adresa efectiv prin sumarea deplasamentului cu baza i cu index multiplicat cu n. De aici rezult c modurile: indexat, bazat/indexat i bazat/indexat/deplasament sunt cazuri speciale ale modului de adresare scalat indexat cu n egal cu unu. Urmtoarele perechi de instruciuni sunt perfect identice pentru 80386: mov al, 2[ebx][esi*1] mov al, [ebx][esi*1] mov al, 2[esi*1] mov al, 2[ebx][esi] mov al, [ebx][esi] mov al, 2[esi]

Bineneles c MASM permite o mulime de variaiuni la aceste moduri de adresare. Urmtoarele instruciuni ilustreaz o mic parte din posibiliti: disp[bx][si*2], disp[si*2][bx], [bx+disp][si*2], [si*2+disp][bx], [bx+si*2+disp], [disp+bx][si*2] [si*2+bx][disp],

2.4.3.5.Cteva consideraii finale asupra modurilor de adresare a memoriei la 80386 Din cauz c modurile de adresare la procesorul 80386 sunt mult mai coerente ele sunt mult mai uor de memorat dect modurile de adresare ale procesorului 8086. Pentru programatorii care lucreaz cu procesorul 80386 exist ntotdeauna tentaia de a neglija modurile de adresare 8086 i de a folosi pe cele ale lui 80386 n mod exclusiv. Cu toate acestea, aa cum se va arta, modurile de adresare 8086 sunt n realitate mai eficiente dect modurile comparabile ale lui 80386. Aadar este important s se 56

cunoasc toate modurile de adresare i s se aleag modul convenabil pentru o problem dat. Cnd se utilizeaz modurile de adresare bazat/indexat i bazat/indexat/deplasament la 80386 fr opiunea de scalare (asta nsemnnd s se lase scalarea implicit la *1), primul registru care apare n modul de adresare este registrul baz iar cel de-al doilea este registrul index. Acesta este un lucru important din cauz c registrul de segment implicit este ales dup registrul baz. Dac registrul baz este ebp sau esp atunci registrul segment implicit este registrul de stiv. n toate celelalte cazuri 80386 acceseaz segmentul de date implicit chiar dac registrul index este ebp. Dac utilizai operatorul de scalare al indexului (*n) la un registru, acel registru va fi registrul index indiferent unde apare n modul de adresare: [ebx][ebp] [ebp][ebx] [ebp*1][ebx] [ebx][ebp*1] [ebp][ebx*1] [ebx*1][ebp] es:[ebx][ebp*1] ;Folosete implicit DS. ; Folosete implicit SS. ; Folosete implicit DS. ; Folosete implicit DS. ; Folosete implicit SS. ; Folosete implicit SS. ; Folosete ES.

2.5.

Instruciunea MOV la procesorul 8086

Structura instruciunii mov (move) care este una dintre cele mai utilizate instruciuni este: mov Destinaie,Surs

Instruciunea mov face o copie a valorii sursei pe care o stocheaz n destinaie. Instruciunea nu afecteaz coninutul sursei ci numai cel al destinaiei. Pentru a nelege complexitatea instruciunii mov trebuie s studiem modul de codificare a acesteia. n figura urmtoare este prezentat forma cea mai utilizat pentru codificarea binar a instruciunii mov.

Instruciunea MOV generic Codul operaiei se gsete n primii 8 bii ai instruciunii. Biii zero i unu definesc dimensiunea instruciunii (8, 16 sau 32 bii) i direcia transferului (acestea sunt simbolizate cu w i d). Urmeaz octetul modului de adresare numit octetul modreg-r/m de ctre majoritatea programatorilor. Acest octet care poate acea 256 de valori 57

diferite i ele reprezint combinaiile posibile pentru operanzi la instruciunea mov generic. Instruciunea mov generic are trei forme diferite n limbajul de asamblare: mov reg, memory mov memory, reg mov reg, reg Trebuie reinut faptul c cel puin unul din operanzi este ntotdeauna un registru de uz general. n cmpul reg al octetului mod/reg/rm este specificat acest registru de uz general (sau unul din registre n forma a treia de mai sus). Bitul d (direcie) din codul operaiei indic faptul c instruciunea va stoca data ntr-un registru (d = 1) sau n memorie (d = 0). Biii din cmpul reg permite alegerea unui registru din 8 posibile. 8086 are 8 registre de 8 bii i 8 registre de 16 bii de uz general. 80386 mai are suplimentar 8 registre de 32 de bii de uz general. Modul de decodificare a tipului de registru de ctre unitatea central este prezentat n tabelul urmtor:

Pentru a diferenia registrele de 16 sau 32 de bii procesoarele 80386 i urmtoarele folosesc un prefix special la codul operaiei la instruciunile ce folosesc registre de 32 de bii. n rest codificarea instruciunii este aceeai la cele dou tipuri de instruciuni. Cmpul r/m n conjuncie cu cmpul mod stabilete modul de adresare. Codificarea cmpului mod este urmtoarea:

58

Cmpul mod selecteaz ntre transferul registru la registru i transferul ntre registru i memorie. De asemenea se selecteaz dimensiunea deplasamentului (zero, unu, doi sau patru bii) folosii n instruciunile pentru modurile de adresare a memoriei. Dac MODD=00 atunci este selectat unul din modurile de adresare fr deplasament (indirect prin registre sau bazat/indexat). Trebuie reinut cazul special cnd MOD=00 i r/m=110 care n mod normal ar corespunde modului de adresare [bp]. 8086 utilizeaz aceast codificare pentru modul de adresare numai deplasament. Asta nseamn c nu exist un mod de adresare [bp] adevarat la 8086. Pentru a nelege de ce nu putem utiliza n programe modul de adresare [bp] s privim la MOD=01 i MOD=10 din tabelul de mai sus. Aceste configuraii activeaz modurile de adresare disp[reg] i disp[reg][reg] iar acestea nu sunt aceleai cu modul de adresare [bp]. S considerm urmtoarele instruciuni: mov al, 0[bx] mov ah, 0[bp] mov 0[si], al mov 0[di], ah Aceste instruciuni, ce folosesc modurile de adresare indexat, realizeaz aceleai operaii ca i dublurile lor cu adresare indirect cu registre (obinute prin ndeprtarea deplasamentului n instruciunile de mai sus). Singura diferen real ntre cele dou forme este aceea c modul de adresare indexat este de un octet (dac MOD=01) i de doi octei (dac MOD=10) pentru a reine deplasamentul lui zero. Din cauz c ele sunt mai lungi atunci aceste instruciuni vor dura mai mult (execuia va fi mai lent). Aceste trsturi ale procesorului 8086 de a furniza dou sau mai multe ci pentru a realiza acelai lucru apar n ntregul set de instruciuni. Dei exist mai multe forme MASM selecteaz automat forma cea mai bun (adecvat). Dac scriei instruciunile de mai sus i le asamblai cu MASM vei vedea c se genereaz modul de adresare indirect pentru toate instruciunile cu excepia instruciunii mov ah,0[bp]. Asamblorul va ncerca ntotdeauna s emit numai deplasamente de un octet pentru aceste instruciuni sunt mai scurte i mai rapide dect instruciunile cu deplasament pe doi octei (dan inex zero). Trebuie notat faptul c MASM nu v cere s introducei 0[bp] ci trebuie s introducei numai [bp] iar MASM va furniza zero automat. Dac MOD nu este egal cu 11b, cmpul r/m codific modul de adresare al memoriei n felul urmtor:

Aceste explicaii justific faptul c instruciunile procesoarelor Intel sunt de tip CISC (Complex Instruction Set Computer). 59

2.6.

Comentarii finale asupra instruciunilor MOV

Sunt cteva lucruri importante ce trebuie reinute n legtur cu instruciunea mov. Mai nti de toate nu se poate face transferul direct de la memorie la memorie. Pentru a putea face acest transfer este necesar un grup de dou instruciuni, una pentru transferul coninutului memoriei ntr-un registru i una pentru transferul coninutului registrului n memorie. Un alt fapt important ce trebuie reinut n legtur cu instruciunea mov este faptul c exist mai multe instruciuni mov diferite care realizeaz acelai lucru. De asemenea sunt mai multe moduri de adresare diferite ce pot fi folosite pentru accesarea aceleiai locaii de memorie. Dac dorii s scriei cel mai scurt program posibil n limbaj de asamblare trebuie s cntrii tot timpul care dintre instruciuni este cea mai convenabil. Discuia din acest capitol s-a fcut pentru instruciunea mov generic pentru a vedea cum procesorul 80x86 codific modurile de adresare la memorie i registre la acest tip de instruciune. Alte forme ale instruciunii mov v permit transferul datelor ntre registrele de uz general de 16 bii i registrele segment 80x86 sau ncrcarea registrelor sau a locaiilor de memorie cu o constant. Aceste variante ale instruciunii mov au alte coduri operaie. De asemenea sunt mai multe instruciuni mov suplimentare la procesorul 80386 care v permit ncrcarea registrelor de uz special ale acestuia ce nu au fost prezentate aici. Trebuie reamintite aici i instruciunile pe iruri ale procesoarelor 80x86 ce realizeaz transferuri memorie la memorie care pot fi un bun substituent pentru instruciunile mov.

2.7.

Cteva instruciuni suplimentare

Instruciunile: LEA (load effective address). LES (load es and general purpose register), ADD (addition) i MUL (multiply) ca i instruciunea MOV prezentat anterior se dovedesc folositoare pentru accesarea diferitelor tipuri de date. Instruciunea LEA are urmtoarea form: lea reg16, memory unde reg16 este un registru de uz general pe 16 bii. Memory este o locaie de memorie reprezentat de un octet mod/reg/rm (cu excepia faptului c trebuie s fie o locaie de memorie i nu poate fi un registru). Aceast instruciune ncarc registrul de 16 bii cu ofsetul locaiei specificate de operandul memory. Instruciunea: lea ax,1000h[bx][si] de exemplu, va ncrca registrul ax cu adresa locaiei de memorie specificat de 1000h[bx][si], care este desigur valoarea dat de 1000h+bx+si. Instruciunea este foarte folositoare pentru obinerea adresei unei variabile. Dac avei o variabil I undeva n memorie, instruciunea: lea bx,I va ncrca registrul bx cu adresa (ofsetul) variabilei I. Instruciunea LES are urmtoarea form: les reg16, memory32

60

Instruciunea ncarc registrul es i unul din registrele de uz general de la adresa de memorie specificat. Trebuie notat faptul c adresa de memorie poate fi specificat cu octetul mod/reg/rm dar c la instruciunea lea trebuie s fie o locaie de memorie i nu un registru. Instruciunea les ncarc registrul de uz general specificat cu cuvntul de la adresa specificat i registrul es cu urmtorul cuvnt din memorie. Aceast instruciune este companionul instruciunii lds (care ncarc registrul ds) i sunt singurele instruciuni pe 32 de bii la mainile pre-80386. Instruciunea add la fel ca la x86 adun dou valori. Instruciunea poate avea mai multe forme dar acum ne intereseaz urmtoarele cinci forme: add add add add add reg, reg reg, memory memory, reg reg, constant memory, constant

Toate aceste instruciuni adun cel de-al doilea operand la primul lsnd rezultatul n primul operand. De exemplu add bx,5 calculeaz bx:=bx + 5. Ultima instruciune este mul (multiply), instruciune ce are un singur operand i are forma: mul reg/memory Sunt mai multe detalii importante n ceea ce privete instruciunea mul pe care acest capitol le ignor. Locaia de memorie sau registrul sunt de 16 bii. n acest caz instruciunea calculeaz dx:ax := ax*reg/mem. Pentru aceast instruciune nu avem modul imediat de adresare.

2.8.

Structura unui program n limbaj de asamblare

Programul n limbaj de asamblare este alctuit din mai multe linii surs. 0 linie surs este alctuit din urmtoarele elemente: <Eticheta> <Mnemonicul> <Operanzii> <Comentariul> <Eticheta> este un nume simblic asociat unei adrese (locaii) de memorie. <Mnemonicul> se refer la denumirea codului operaiei unei instruciuni, de exemplu add, mov etc. Acest atom lexical poate fi ns i o directiv (pseudo - operaie), de exemplu .code, .data, dosseg etc. Directivele servesc la efectuarea anumitor aciuni de ctre asamblor, n timp ce instruciunile permit realizarea anumitor operaiuni. <Operanzii> nsoesc de regul aceste categorii enumerate mai sus (instruciuni, directive). De pild, instructiunea mov posed doi operanzi: mov ax, @data iar directiva de mai jos, un singur operand: .stack 200h <Comentariul>, ultimul din atomii lexicali este constituit dintr-o niruire de cuvinte text explicativ - precedat de separatorul punct i virgul. 61

Cei patru atomi lexicali nu trebuie s fie toi prezeni pe o aceeai linie de program Eticheta poate fi izolat pe o linie, mnemonicul pe alta, el fiind urmat de operanzi. Comentariul poate s se ntind pe mai multe linii, dar fiecare va trebui s nceap cu separatorul punct i virgul. Atomii lexicali sunt desprii prin blancuri sau tab-uri sau CR. Blank-urile, tab-urile, punctul i virgula se numesc separatori. 2.8.1. Directivele de segmentare Un program este alctuit din cel puin un segment de cod, unul de date i unul de stiv. Sub sistemul de operare DOS sunt posibile ase modele de memorie. Prin model de memorie se nelege de fapt un mod de dispunere n memoria RAM a segmentelor ce alctuiesc un program. n tabelul 2.1 se prezint aceste modele (s-a notat cu LP, LD i LS lungimea segmentului de cod program , date respectiv stiv). Tabelul 2.1. Modelul foarte mic (tiny) mic (small) mediu (medium) compact (compact) mare (large) foarte mare (huge) Lungimea diferitelor componente LP + LD + LS < 64ko LP < 64ko i LD + LS < 64ko 64 ko LP < 1 Mo i LD + LS < 1 Mo LP < 64 ko i 64 ko LD + LS < 1 Mo 64 ko LP < 1Mo i 64ko LD + LS < 1Mo idem large, doar punctatorii vor fi normalizai

Pentru macroasamblorul MASM sau TASM, directivele simplificate de segmentare sunt: .code, .data i .stak pentru segmentele de cod (program), date i respectiv, stiv. Exemplul 1 prezint un program n limbaj de asamblare cu directive simplificate de segmentare. Exemplul 1.
;Un program care nu face nimic... ;El arata cum se stabilesc segmentele simplificat ;Programul nu poate fi lansat in executie din cauza ca nu are ;apel functie DOS de iesire din program dosseg .model small .stack 200h .data .code end

Acest program, dei este corect scris, nu poate fi lansat n execuie deoarece nu conine funcia de rentoarcere n sistemul de operare DOS. Sistemul de operare DOS, atunci cnd lanseaz o aplicaie n execuie, pred controlul acesteia, iar la terminarea aplicaiei, reluarea controlului de ctre sistemul de operare se face prin apelul funciei sistem 4Ch. Apelul unei funcii sistem DOS se face prin lansarea nreruperii 21h dup ce, n prealabil, numrul funciei a fost nscris n registrul ah. Acest lucru se arat n exemplul 2. 62

Un segment ncepe dup directiva corespunztoare a acestuia i se termin la apariia urmtoarei directive. Exemplul 2.
;Un program care nu face nimic... ;El arata cum se stabilesc segmentele simplificat ;Programul poate fi lansat in executie din cauza ca are ;apelul functiei DOS 4Ch de iesire din program dosseg .model small .stack 200h .data .code Start: mov ah,4ch int 21h end Start

n exemplul 2, pentru stiva se rezerv 512 octei iar nceputul programului este marcat de eticheta Start. Pentru obinerea fiierului executabil vom folosi turboasamblorul TASM.EXE. La lansarea n execuie a programului TASM.EXE se afieaz:
Turbo Assembler Version 3.2 Copyright (c) 1988, 1992 Borland International Syntax: TASM [options] source [,object] [,listing] [,xref] /a,/s Alphabetic or Source-code segment ordering /c Generate cross-reference in listing /dSYM[=VAL] Define symbol SYM = 0, or = value VAL /e,/r Emulated or Real floating-point instructions /h,/? Display this help screen /iPATH Search PATH for include files /jCMD Jam in an assembler directive CMD (eg. /jIDEAL) /kh# Hash table capacity # symbols /l,/la Generate listing: l=normal listing, la=expanded listing /ml,/mx,/mu Case sensitivity on symbols: ml=all, mx=globals, mu=none /mv# Set maximum valid length for symbols /m# Allow # multiple passes to resolve forward references /n Suppress symbol tables in listing /os,/o,/op,/oiObject code: standard, standard w/overlays, Phar Lap, or IBM /p Check for code segment overrides in protected mode /q Suppress OBJ records not needed for linking /t Suppress messages if successful assembly /uxxxx Set version emulation, version xxxx /w0,/w1,/w2 Set warning level: w0=none, w1=w2=warnings on /w-xxx,/w+xxx Disable (-) or enable (+) warning xxx /x Include false conditionals in listing /z Display source line with error message /zi,/zd,/zn Debug info: zi=full, zd=line numbers only, zn=none

Programul TASM.EXE se folosete n modul limie de comand unde se precizeaz: opiunile, numele fiierului surs i opional numele fiierului obiect, list i referine ncruciate. Pentru a asambla fiierul din exemplul 2 se folosete linia de comand (numele fiierului surs este tdan2.asm): TASM /l /zi /os tdan2 63

se obine un fiier n cod obiect relocabil tdan2.obj i un fiier list tdan2.lst. Fiierul list este prezentat n continuare.
Turbo Assembler tdan2.ASM 1 2 simplificat 3 cauza ca are 4 5 6 0000 7 0000 8 0000 9 0000 10 0000 11 0000 B4 4C 12 0002 CD 21 13 Turbo Assembler Symbol Table Symbol Name ??DATE ??FILENAME ??TIME ??VERSION @32BIT @CODE @CODESIZE @CPU @CURSEG @DATA @DATASIZE @FILENAME @INTERFACE @MODEL @STACK @WORDSIZE START Groups & Segments DGROUP STACK _DATA _TEXT Version 3.2 04/12/07 09:55:58 Page 1

;Un program care nu face nimic... ;El arata cum se stabilesc segmentele ;Programul poate fi lansat in executie din

;apelul functiei DOS 4Ch de iesire din program dosseg .model small .stack 200h .data .code Start: mov ah,4ch int 21h end Start Version 3.2 04/12/07 09:55:58 Page 2

Type

Value

Text "04/12/07" Text "tdan2 Text "09:55:58" Number 0314 Text 0 Text _TEXT Text 0 Text 0101H Text _TEXT Text DGROUP Text 0 Text TDAN2 Text 00H Text 2 Text DGROUP Text 2 Near _TEXT:0000

"

Bit Size Align Combine Class Group 16 0200 Para Stack STACK 16 0000 Word Public DATA Public CODE 16 0004 Word

Pentru obinerea programului n cod obiect direct executabil se folosete editorul de legturi TLINK.EXE. Acest program poate elabora att programme cu extensia .com (cu dimensiunea maxima de 64ko) ct i programme cu extensia .exe (care pot avea dimensiuni mai mari de 64ko). Lansarea n execuie a programului duce la afiarea textului urmtor. 64

Turbo Link Version 3.0 Copyright (c) 1987, 1990 Borland International Syntax: TLINK objfiles, exefile, mapfile, libfiles @xxxx indicates use response file xxxx Options: /m = map file with publics /x = no map file at all /i = initialize all segments /l = include source line numbers /s = detailed map of segments /n = no default libraries /d = warn if duplicate symbols in libraries /c = lower case significant in symbols /3 = enable 32-bit processing /v = include full symbolic debug information /e = ignore Extended Dictionary /t = create COM file /o = overlay switch /ye = expanded memory swapping /yx = extended memory swapping

Linia de comand pentru obinerea fiierului de tip .exe este: TLINK tdan2 /v se genereaz un fiier cu extensia .exe n cod obiect direct executabil i un fiier text cu extensia .map ce conine informaii despre alocarea memoriei:
Start Stop Length Name Class 00000H 00003H 00004H _TEXT CODE 00004H 00004H 00000H _DATA DATA 00010H 0020FH 00200H STACK STACK Program entry point at 0000:0000

Pentru obinerea unui unui fiier direct executabil cu extensia .com se adaug opiunea /t. Programele n format .exe difer structural de cele n format .com. Pentru a exemplifica acest lucru vom folosi acelai program scris pentru obinerea formatului .exe (exemplul 3) i pentru obinerea formatului .com (exemplul 4). Prin analiza celor dou exemple ne putem da seama de structura fiecrui tip de program. Exemplul 3. Program scris n scopul linkeditrii n format .exe
;Program care determina numarul de unitati de disc din sistem si ;afiseaza acest numar stiva segment STACK 'STACK' dw 100H dup (?) stiva ends code SEGMENT assume cs:code, ds:code ; ; Datele programului ; text1 db 'In configuratie sunt $' text2 db ' unitati de disc flexibil$'

65

; ;

Codul programului

inceput: mov mov mov mov int

ax,code ds,ax ah,9 dx,offset text1 21H ;afisarea primului text ;ds:dx indica adresa de inceput a textului ;textul se incheie cu caracterul $ int 11H ;determinare configuratie and al,0C0H ;se indica bitii care indica ;numarul unitatii de disc

; ; ; Construieste codul ASCII al numarului de unitati de disc mov shr add mov ; ; ; cl,6 al,cl al,1 + '0' dl,al

;salvare caracter

tiparire numar de unitati de disc mov ah,2 int 21H

;apel DOS pentru afisarea caracterului ;din registrul dl

; ; ;

Tiparire sfarsit text mov ah,9 mov dx,offset text2 int 21H

; ; ;

Sfarsit executie program format EXE mov ax,4c00h int 21H ends end inceput

code

Exemplul 4. Program scris n scopul linkeditrii n format .com (opiunea /t)


;Modul de realizare a exemplului 3 sub forma de program COM ; code SEGMENT assume cs:code, org 100H

ds:code

start: jmp ; ; ;

short inceput

Datele programului

66

text1 db 'In configuratie sunt $' text2 db ' unitati de disc flexibil$' ; ; Codul programului inceput: mov mov int

ah,9 dx,offset text1 21H ;afisarea primului text ;ds:dx indica adresa de inceput a textului ;textul se incheie cu caracterul $ int 11H ;determinare configuratie and al,0C0H ;se indica bitii care indica ;numarul unitatii de disc

; ; ; Construieste codul ASCII al numarului de unitati de disc mov shr add mov ; ; ; cl,6 al,cl al,1 + '0' dl,al

;salvare caracter

tiparire numar de unitati de disc mov ah,2 int 21H

;apel DOS pentru afisarea caracterului ;din registrul dl

; ; ;

Tiparire sfarsit text mov ah,9 mov dx,offset text2 int 21H

; ; ;

Sfarsit executie program format COM mov ax,4c00h int 21H code ends end start

Un program cu directive de segmentare complete este prezentat n exemplul 5. Exemplul 5.


;program cu directive de segmentare complete ;evident ca programul nu face nimic dar poate fi rulat ;pentru ca are apelul functiei DOS de iesire din program ;Prima data definim segmentul de stiva. ;In acest segment se rezerva 512 octeti care sunt initializati cu zero ;cuvintul scris intre ghilimele da indicatii linkeditorului cum sa ;grupeze datele Stiva SEGMENT para public stack 'stiv' db 200h dup(0)

67

Stiva ENDS ;Vom defini mai departe doua segmente de date diferite Date1 SEGMENT word public 'data' ;primul segment de date param1 db 5 Date1 ENDS Date2 SEGMENT word public 'data' ;al doilea segment de date param2 db 9 Date2 ENDS ;Si in sfirsit segmentul de cod Cod SEGMENT word public 'code' ; ASSUME cs:Cod ;Inceputul programului Start: mov ax,Date1 mov ds,ax ;Adresarea segmentului Date1 ASSUME ds:Date1 mov ax,Date2 mov es,ax ;Adresarea segmentului Date2 ASSUME es:Date2 ; ; mov ax,Stiva ;Aceasta secventa de fapt nu e necesara... mov ss,ax ;Adresarea segmentului de stiva ASSUME ss:Stiva ;Programul propriu-zis mov al,param1 mov al,param2 ;Aici evident se pune secventa de iesire mov ah,4ch int 21h Cod Ends end Start

Acest stil de programare ofer o mai mare flexibilitate n privina amplasrii n memorie a segmentelor. Se remarc amplasarea directivelor SEGMENT i ENDS care delimiteaz un segment al crui nume apare n faa ambelor directive. Directivele pot fi scrise cu litere mai sau mici. Segmentul este o grupare logic de elemente, adresate prin intermediul unui registru de segment. Elementele ce l alctuiesc pot fi instruciuni i/sau date. Cuvntul rezervat PARA (provine de la paragraph ) este un operand al directivei SEGMENT, prin care se anun c implantarea segmentului se va face la o adres multiplu de 16. n schimb _TEXT i _DATE vor fi alineate la adrese multiplu de doi (operandul WORD). n sfrit cuvntul rezervat PUBLIC va face cunoscute denumirile acestor segmente n exteriorul programului (util pentru linkeditor). Directiva ASSUME asociaz un registru de segment la segmentul respectiv. 68

2.8.2. Directivele pentru definirea datelor Se permit urmtoarele forme de definire a datelor: o o o o o o o definirea unui octet (define byte, db sau DB) ; definirea unui cuvnt (define word, dd sau DD); definirea unui dublu cuvnt (define double word, dw sau DW); definirea unui cuvnt de 6 octei (define float, df sau DF); la fel (define pointer, dp sau DP); definirea unui cuvnt de 8 octei (define quad word, dq sau DQ); definirea unei zone de 10 octei (define ten bytes, dt sau DT).

2.8.3. Concluzii privind limbajul de asamblare Un program scris n limbaj de asamblare urmrete topica urmtoare: o Controlul segmentrii i adresrii (SEGMENT/ENDS, ASSUME, GROUP) incluznd ncrcarea registrelor de segment, a segmentelor de cod i diverse consideraii asupra instruciunilor de ir (MOVS, MOVSB). o Definirea etichetelor (LABEL). o Definirea procedurilor (PROC, ENDP). o Legarea programelor (NAME, END, PUBLIC, EXTRN). o Controlul numrtorului de instruciuni (ORG). Segmentul este cea mai mic unitate de memorie relocabil i el are cel mult 64 ko. Fiecare bloc este continuu (nu sunt permise guri n segment) dar segmentele pot fi mprtiate prin memorie. Putei defini cte segmente dorii dar trebuie s fie definit cel puin unul pe modul de asamblare (dac se omite instruciunea de definire a segmentului, asamblorul asigneaz automat numele ??SEG). Fiecare instruciune i fiecare dat din programul dumneavoastr trebuie s aparin unui segment. Nu exist nimic care s mpiedice amestecarea codului i a datelor n segmente. Cteva exemple practice de segmentare sunt: o o o o o o o un segment pentru date globale; un segment pentru date locale; un segment pentru stiva; un segment pentru programul principal; un segment pentru subrutinele reentrante; un segment pentru vectorii de ntrerupere; un segment pentru rutinele de ntreruperi.

Un segment fizic const din cel mult 65535 (64K) octei ncepnd de la o adres absolut divizibil prin 16. O astfel de adres se numete limit de paragraf. Cum un segment logic nu e necesar s nceap la o limit de paragraf, nu e necesar ca segmentele logice s corespund celor fizice. 69

Cum fiecare segment ncepe n anumite paragrafe, registrele de 16 bii (CS, DS, ES, SS) sunt folosite s pstreze numerele paragrafelor unde ncep segmentele. La execuie, fiecare referin la memorie necesit dou componente pentru adresarea fizic propriu-zis: 1. Valoarea bazei segmentului de 16 bii ce este coninut ntr-unul din registrele CS, DS, SS, ES. 2. O adres efectiv de 16 bii care d offset-ul memoriei. Adresa propriu-zis (fizic) este calculat :
adresa fizic (20 biti) = 16 * (adresa de baza a segmentului) + adresa efectiva (offset)

Posibilitile operanzilor Operanzii din memorie pot fi adresai direct cu o adres de offset de 16 bii, sau indirect cu baza (BX sau BP) i/sau indexul (SI sau DI) adunate la un deplasament opional de 8 sau 16 bii. Rezultatul unei operaii cu doi operanzi poate fi pus direct n memorie sau registru. Operaiile cu un singur operand se aplic oricrui operand, excepie constantele imediate. Legatura segmentrii cu modulele de asamblare Modulul de asamblare poate rezulta din: o o o o parte de segment un segment pri din mai multe segmente mai multe segmente

i orice combinaie a acestora n funcie de utilizarea directivelor SEGMENT/ENDS. Dup asamblare se pot combina din nou cu ajutorul programului LINK. Controlul segmentrii i adresarea In timpul execuiei orice instruciune i variabil se gsete n cadrul unui anumit segment. Dac nu i-ai dat un nume asamblorul creeaz automat unul, ??SEG. Pentru a numi segmentul, a controla alinierea i continuitatea lui se folosesc directivele SEGMENT, ENDS: [nume-seg] SEGMENT [tip aliniere][tip combinare]['nume clasa'] . . . [nume-seg] ENDS unde: 70

tip aliniere specific la ce tip de limit va fi locatat segmentul: 1. PARA - (automat) - la o adres divizibil cu 16 (ceea mai puin semnificativ cifra egal cu 0) ; 2. BYTE - oriunde ; 3. WORD - la o adres limit de tip cuvnt (cel mai puin semnificativ bit 0) ; 4. PAGE - la o adres limit de tip pagin (ultimele dou cifre hexa 0) ; 5. INPAGE - ntreg segmentul ocup mai puin de 256 octei i acesta, locatat, nu trebuie s depeasc limita paginii. tip combinare specific cum acest segment poate fi combinat cu alte segmente pentru legare i locatare: 1. necombinabil 2. PUBLIC - specific faptul c acest segment va fi concatenat cu altele, de acelai nume la legare (LINK) 3. COMMON - specific c acest segment i toate segmentele de acelasi nume care se leag mpreuna vor ncepe la aceeai adres, astfel suprapunndu-se. Lungimea este cea corespunztoare lungimii segmentului maxim legat. 4. AT expresie - specific c acest segment va fi locatat la un paragraf evaluat de expresia data (ex: AT 4444H nseamn o adres absolut de memorie. Expresia poate fi orice expresie valid rezultnd o constant, dar nu se permit referine nainte). 5. STACK - specific c acest segment este o parte din stiva de execuie, adresat de tip LIFO. Aceste segmente sunt puse naintea memoriei mari i cresc descresctor. Memoria alocat segmentului de stiv este suma alocrilor pentru fiecare segment individual. 6. MEMORY - specific c acest segment trebuie locatat deasupra tuturor segmentelor legate mpreun. Dac se ntlnesc mai multe segmente de tip MEMORY numai primul este tratat ca atare, restul sunt tratate ca segmente COMMON. 'nume clasa' specific un nume de clas pentru segment: o o o o o CODE CONST DATA STACK MEMORY

Segmente nlnuite Segmentele nu sunt niciodat nlnuite fizic, totui este permis s se codifice o poriune a unui segment, se pornete i se sfrete altul, apoi se revine la codificarea primului. Asamblorul de fapt concateneaz a doua poriune a segmentului la prima. Nu se permite suprapunerea segmentelor ci doar nlnuirea lor lexical. 71

Directiva ASSUME Directiva ASSUME construiete o legatur simbolic ntre: o definirea instruciunilor n timpul asamblrii i datele n segmentele logice i o evenimentele de executare a instruciunilor cu registrele de segment. Cu alte cuvinte, ASSUME e o promisiune data asamblorului ca instruciunile i datele sunt adresate n timpul execuiei prin intermediul anumitor registre. Incrcarea actual i manipularea valorilor este responsabilitatea programatorului. ASSUME permite asamblorului s verifice c fiecare data i instruciune este adresat corespunztor. Directiva LABEL Directiva LABEL creeaz un nume pentru locaia curent de asamblare, dat sau instruciune. nume LABEL tip unde : nume este asignat atributelor urmtoare: o segment - segmentul curent de asamblare; o offset - offset-ul in cadrul segmentului curent; o tip - operandul lui LABEL. tip poate fi : o NEAR sau FAR dac urmeaz cod executabil. Eticheta poate fi utilizat n JMP sau CALL dar nu n MOV sau alte instruciuni de manipulare a datelor ; o BYTE, WORD, DWORD, nume de structura sau nume de nregistrare dac urmeaz date. Se poate indexa un identificator declarat cu LABEL dac directiva asigneaza un tip: BYTE, WORD. In acest caz numele este o variabil i e valid n MOV dar nu n JMP sau CALL. Principalele utilizri ale lui LABEL sunt: o a accesa variabile (tablouri) prin BYTE sau WORD dup cum e nevoie ; o definirea unei etichete de tip FAR ;

72

o furnizarea unei etichete de tip NEAR, existente, care are valoare de segment i offset determinate, calitatea de FAR, putnd fi astfel accesate i din alte segmente. Proceduri (directivele PROC/ENDP) Limbajul de asamblare furnizeaz proceduri pentru a implementa conceptul de subrutina. nume PROC [NEAR/FAR] . . . RET . . . nume ENDP unde "nume" este un identificator care trebuie s apar n PROC i ENDP. Se asigneaz tipul NEAR sau FAR dup cum este specificat, implicit este NEAR. Trebuie specificat FAR dac procedura va fi apelat din cod cu alt valoare ASSUME CS:. Tipul procedurii determin dac RET este asamblat NEAR sau FAR. Apelul unei proceduri Cnd se apeleaz o procedura NEAR, numrtorul de instruciuni este salvat (IP) n stiv i se transmite controlul primei instruciuni din procedur. Cnd se apeleaz o procedur FAR, registrul CS i apoi IP sunt salvate n stiv i se transfer controlul. Se permit puncte de intrare multiple ntr-o procedur, tipul acestor puncte poate fi diferit. Intoarcerea din proceduri O procedur se termin cnd se specific instruciunea RET (din rutina de ntreruperi IRET). Pot apare mai multe RET-uri n procedura i nu e necesar ca ultima instruciune s fie RET. ntoarcerea dintr-o procedur FAR va pune vrful stivei n IP i urmtorul cuvnt n CS; la o procedur NEAR vrful stivei se pune n IP. Dac procedura utilizeaz stiva pentru memorarea unor date temporare, aceste date trebuie s fie descrcate nainte de ntoarcerea din procedur.

Directive pentru legarea programelor NAME/END, PUBLIC, EXTRN Utiliznd LINK si LOCATE se pot lega i reloca n vederea execuiei mai multe module de program ntr-unul singur. 73

Pentru a identifica referinele simbolice intermodulare se pot utiliza directivele: o NAME - asigneaz un nume modulului obiect generat de asamblor o PUBLIC - specific simboli definii n acest modul de asamblare ai cror atribute sunt fcute disponibile altor module n faza de legare o EXTRN - specific simboli definii n alte module de asamblare ale cror atribute sunt necesare acestui modul n faza de legare O bun programare urmrete declararea etichetelor externe i a variabilelor ntrun fiier INCLUDE pentru fiecare modul asamblat care conine declaraii EXTRN pentru toi simbolii declarai PUBLIC n el. Fiierul INCLUDE ar trebui s conin perechi SEGMENT PUBLIC/ENDS pentru fiecare segment i ntre ele o directiv EXTRN listnd variabilele (cu tipurile lor) pentru acest segment. END [nume eticheta] exist un singur END ntr-un fiier surs i trebuie s fie ultima instruciune. Dac exist, "nume eticheta" este folosit ca adres de start pentru execuia programului. Dac sunt mai multe module de legat mpreun, numai unul poate specifica o adres de start. Acest modul este modulul principal. Numrtorul de instruciuni ($) i directiva ORG Numrtorul de instruciuni conine o valoare (reprezentat simbolic prin ($)) care spune asamblorului ce offset n segmentul curent are urmtoarea instruciune sau data de asamblat. Directiva ORG poate fi utilizat pentru a ncrca cu o anumit valoare numrtorul de instruciuni ORG expresie unde "expresie" este evaluat modulo 65536 i trebuie s nu conin nici o referin nainte. Directiva nu poate avea etichet. Utilizarea operatorului SHORT Cnd saltul este n interiorul segmentului i deplasamentul relativ al lui este n gama -128 si 127 de octei i scopul (inta) etichetei nu a fost nc definit, poi salva un octet prin codificarea operatorului SHORT naintea etichetei. PTR este util, ca n exemplele urmtoare: o incrementarea unui octet sau cuvnt din memorie: INC BYTE PTR [BX] INC WORD PTR [SI] o mut o valoare imediat ntr-un octet sau cuvnt din memorie: 74

MOV WORD PTR [DI],99 MOV BYTE PTR [DI],99 o salt cu dou nivele de indirectare: JMP DWORD PTR [BX] Operatorii HIGH si LOW Se mai numesc i operatori de izolare a octetului. Accept ca argument un numr sau o expresie de tip adres, HIGH ntoarce octetul mai semnificativ; LOW cel mai puin semnificativ. Ierarhia operatorilor Clasele de operatori n ordine descresctoare de precedenta sunt: 1) expresii cu paranteze, paranteze drepte la expresii, paranteze rotunde la expresii, (.) n structuri, LENGTH, SIZE, WIDTH, MASK. 2) PTR, OFFSET, SEG, TYPE, THIS i "nume:" (suprapunere de segmente). 3) HIGH, LOW. 4) /, *, MOD, SHL, SHR 5) +, 6) relaionali : EQ, NE, LT, LE, GT, GE 7) NOT logic 8) AND logic 9) OR, XOR logic 10) SHORT Directiva EQU Unui simbol i se poate asigna o valoare n timpul asamblrii utiliznd EQU. Formatul este: nume EQU expresie Prezentm n continuare cteva exemple de programe scrise n limbaj de asamblare. Exemplul 6.
;Program care prezinta un mod de rezervare a stivei stiva segment stack dw 100 dup(0)

varf_stiva label word stiva ends initializare_stiva segment assume cs:initializare_stiva, ss:stiva

;initializare cu zero a unei zone ;de 100 x 2 octeti ;asociere nume pentru aceasta adresa

75

start:

mov ax,stiva ;actualizare registru segment stiva mov ss,ax mov sp,offset varf_stiva ;actualizare indicator varf stiva

; ;incheiere program mov ax,4c00h int 21h initializare_stiva ends end start

Exemplul 7.
;Varianta cu directive de segmentare complete ;Programul realizeaza suma a doua numere ;Programul arata definirea si apelul unei proceduri ; StkSegment segment para stack 'stack' db 512 dup(?) StkSegment ends ; DataSegment segment word 'data' Lista1 db 6,8,? Lista2 db 10,35,? DataSegment ends ; CodSegment segment word 'code' assume cs:CodSegment,ds:DataSegment,ss:StkSegment ;Procedura de adunare a doua valori reprezentate pe cate un octet ;depune rezultatul in memorie peste elementul din fiecare lista ;notat cu ? (locatie de memorie neinitializata) ; adsub proc mov al,[si] add al,[si+1] mov [si+2],al ret adsub endp ; ;Programul principal ;Punctul de intrare ; StartProgram: mov ax,DataSegment mov ds,ax mov si,offset Lista1 call adsub lea si,Lista2 call adsub mov ax,4c00h int 21h CodSegment ends end StartProgram

Exemplul 8.
;Program pentru sortarea in ordine descrescatoare a unui sir cu 10

76

;numere. ;dimensiunea maxima a numerelor de ordonat este de un octet. Numarul ;maxim de numere ale sirului este de 255. ; ;Sumarul utilizarii registrelor ;AH - pastreaza valoarea maxima a numerelor din sir + 1 ;AL - prima valoare din sir de comparat ;BX - contor in sir - BH este nefolosit si este initializat cu zero ;iar BL arata pozitia in sir cu care se compara AH ;DH - contine numarul maxim de termeni ai sirului de comparat ;DL - contine cea de-a doua valoare din sir cu care se compara AL ;CH - stocheaza temporar valoarea DL ;CL - stocheaza temporar valoarea BL ; dosseg ;directiva de segmentare pentru sistemul de operare DOS .model small ;model mic, lungime program < 64 Ko si lungime date ;si lungime stiva (impreuna) < 64 Ko. Compilatorul ;va da un mesaj de eroare daca sunt depasite aceste ;dimensiuni.

.stack 200 .data sir_numere

;pentru stiva sunt rezervati 200 de octeti

;zona de date db 5,1,7,2,8,0,3,6,4,9 ;sirul de numere ce urmeaza a fi ;ordonat index_sir db 0 ;zona de memorie unde se pastreaza indexul curent nr_max_valori db 10 ;numarul maxim de valori pentru sir_numere .code start:

;inceput program

;Sortarea sirului se face astfel: se citeste primul numar si se ;compara cu urmatoarele. Daca se gaseste un numar mai mic acestea se ;inverseaza. La sfirsit numarul este memorat in sir si se trece la ;urmatorul, si asa mai departe. mov ax,@data ;se initializeaza segmentul de date mov ds,ax mov ah,[nr_max_valori] ;AH va pastra numarul maxim de termeni ai ;sirului ;La fel si registrul DH mov dh,ah ;Din motive de comparare in AH vom avea numarul inc ah ;maxim de termeni + 1 mov si,offset sir_numere ;in SI se pune offsetul sirului de ;numere valoare_noua: mov bh,0 ;BH este initializat la zero pt. ca este folosit ;la adresarea sirului mov bl,[index_sir] ;BL contine pozitia primului numar din sir mov al,[bx][si] ;AL prima valoare din sir inc bx ;se trece la urmatoarea valoare din sir cmp dh,bl ;se verifica daca nu s-au comparat toate ;valorile je sfirsit ;s-au comparat toate valorile si s-a terminat ;programul deci fac salt la sfirsit mov [index_sir],bl ;memorez pozitia primei valori de comparat. ;Aceasta va fi comparata succesiv cu valorile ;urmatoare din sir

77

dec bx comparare: inc bx cmp ah,bl

;pentru ca urmeaza o bucla se decrementeaza ;valoarea

;se trece la urmatoarea valoare din sir ;se verifica daca nu s-au comparat toate ;valorile ;din sir je valoare_noua ;daca da, se trece la o alta valoare de ;comparat ;in registrul AL mov dl,[bx][si] ;DL contine valoarea cu care se compara AL, ;valoarea ;urmatoare din sir cmp al,dl ;se compara cele doua valori din sir jb comparare ;daca in AL este o valoare mai mica decit in DL ;atunci se trece la urmatoarea valoare de ;comparat mov cl,bl ;daca nu atunci de inverseaza cele doua valori ;in memorie si in registrele AL si DL. Aici se ;stocheaza temporar indexul in sir mov ch,dl ;se stocheaza temporar valoarea din DL mov [bx][si],al ;se memoreaza valoarea mai mare in locul celei ;mai mici mov bl,[index_sir] ;se determina adresa valorii mai mici dec bl ;aceasta a fost incrementata deci se ;decrementeaza mov [bx][si],dl ;se memoreaza valoarea mai mica mov bl,cl ;se reface indexul sirului (unde s-a ramas cu ;compararea valorilor ;se inverseaza cele doua valori si in registre mov dl,al mov al,ch jmp comparare ;se continua compararea ;programul s-a terminat si ne reintoarcem in sfirsit: ;sistemul de operare mov ax,4c00h ;iesire din program int 21h

end start

2.9.

Scrierea aplicaiilor Windows n limbaj de asamblare

Aplicaiile n limbaj de asamblare sub Windows pot fi realizate n mai multe feluri. Prezentm n continuare includerea unor secvene n limbaj de asamblare n programele scrise pentru Visual Basic. 2.9.1. Includerea limbajului de asamblare n programele Visual Basic Vom explica n continuare noiunile de baz ale amestecrii limbajului de asamblare cu Visual Basic. Nu se explic utilizarea limbajului de asamblare. Codul utilizat aici este realizat cu NASM 0.97 care se poate prelua gratuit de pe Internet. Avertisment: depanarea este extrem de dificil, mediul de programare nefiind n acest caz de nici un folos. Realizarea programului n limbaj de asamblare. De ce avei nevoie: 78

o Visual Basic sau Custom Control Edition gratuit de pe site Microsoft; o NASM gratuit de pe site NASM; o Editor de text. Pentru a utiliza NASM cu Vizual Basic trebuie s construii un DLL cu NASM iar dup aceeea vei utiliza acest DLL cu Visual Basic (VB3 nu permite utilizarea DLLurilor). Utilizarea DLL-ului se face n acelai fel ca DLL-urile sistemului Windows ca user32.dll sau gdi32.dll. Pentru a face un DLL cu NASM se parcurg trei pai: o se scrie codul cu NASM; o dup scrierea codului se linkediteaz cu linker-ul Visul Basic; o apoi se folosete cu Visual Basic. De exemplu vom face un DLL pantru adunarea a doi ntregi (Dwords): Codul n limbaj de asamblare este:
SEGMENT code USE32 GLOBAL _DllMain ;Just a small routine that gets called. mov eax, 1 ;Dont worry about this. _DllMain: retn 12 ;Sub addLongs (ByRef number1 As Long, ByVal number2 As Long) GLOBAL addLongs addLongs: enter 0, 0 mov eax, [ebp+8] ;pointer to number1 mov ecx, [eax] ;ecx = number1 add ecx, [ebp+12] ;ecx = number1 + number2 mov [eax], ecx ;number1 = number1 + number2 leave retn 8 ;return, with 8 bytes of arguments (2 DWords)

ENDS

Prima linie spune asamblorului NASM c este vorba de un program Windows de 32 de bii. Aceast linie trebuie s fie n toate DLL-urile nainte de orice cod. A doua linie spune linkeditorului c _DLLMain va fi un nume global. Linkeditorul va permite ca acest nume s fie apelat de Visual Basic. Trebuie s declarai toate procedurile dumneavoastr ca GLOBAL altfel ele nu vor fi vzute de Visual Basic. A treia linie are numele (eticheta) numit _DllMain i astfel linkeditorul va ti unde este _DllMain. Cele dou linii de cod pe care le are _DllMain fac registrul eax egal cu 1, scoate 12 octei pentru argumentele sale i se rentoarce la apelant. Este o rutin special i nu trebuie s v facei griji n legtur cu ea. Prima linie a celei de-a doua rutin ncepe cu ; (punct i virgul) care arat c este vorba de un comentariu i v arat cum trebuie s o apelai n Visual Basic. Aceasta 79

nseamn c locaia de memorie actual este transferat ca referin pe cnd cellalt argument este transferat ce valoare. Prima variabil este trimis ca referin i deci ea poate fi schimbat pentru c avem locaia acesteia. A doua variabil nu poate fi schimbat de aceast rutin deoarece avem numai valoarea ei. A doua linie (a celei de-a doua rutine) arat c addLongs este o etichet pe care o va vedea i Visual Basic. A treia linie arat unde este addLongs. A patra linie salveaz registrul ebp i l seteaz la nceputul stivei call (acest lucru este necesar numai dac vrei s utilizai argumente). EBP + 8 va fi locaia primului argument. Din cauz c Windows 9x este pe 32 de bii, fiecare argument trebuie s aib 32 de bii, adic 4 octei, iar argumentele sunt unul dup cellalt, al doilea argument va fi la EBP + 12, al treilea la EBP + 16, urmtorul la EBP + 20 i aa mai departe. A cincea linie seteaz EAX la primul argument. Din cauz c primul argument este transferat ca referin, EAX va fi egal cu adresa locaiei de memorie unde este stocat prima variabil. A asea linie face registrul ECX egal cu valoarea primului argument. A aptea linie adun valoarea celui de-al doilea argument la ECX, rezultatul fiind reinut n ECX. A opta linie va seta prima variabil la valoarea ECX. n acest fel numrul1 utilizat n Visual Basic va avea valoarea numrul1 + numrul2. Penultima linie va anula ceea ce a fcut ENTER. Aceasta trebuie folosit dac sa folosit ENTER. Ultima linie marcheaz sfritul rutinei i se rentoarce la apelant (Visual Basic) i arat de asemenea numrul de octei ai argumentului care se trimit acestuia. ENDS arat sfritul fiierului Dup aceasta se face compilarea cu NASM. Se poate folosi un fiier BAT numit MakeDLL.bat unde se trec toate argumentele pentru NASM: C:\Nasm\NasmW.exe f coff myDLL.asm C:\VB5\Link.exe /dll /export:addLongs /entry:DllMain myDll.o del myDLL.exp del myDLL.lib del myDLL.o Prima linie face compilarea n format COFF acceptat de linkeditorul Visual Basic. Dac dorii listingul adugai l myDLL.lst la sfritul primei linii. A doua linie va linkedita formatul COFF .o ntr-un fiier .dll care poate fi folosit cu VB. Primul argument /dll arat c trebuie fcut un fiier DLL. Fr acest argument va fi fcut un fiier EXE. Argumentul /export:addLongs arat c numele addLongs va fi vizibil n VB. Trebuie fcut aceasta pentru orice rutin din DLL altfel VB nu va fi capabil s le gseasc. Urmtorul argument /entry:DllMain arat unde este rutina DLLMain. Acest argument trebuie folosit ntotdeauna. Ultimul argument myDLL.o arat care este fiierul de linkeditat. Apar nite mesaje la prelucrare dar acestea nu se vor lua n considerare.

80

Utilizarea DLL-ului creat n VB. DLL-ul trebuie s fie n acelai director cu programul VB.
Option Explicit Private Declare Sub addLongs Lib "samples\ASM\myDLL" (ByRef number1 As Long , ByVal number2 As Long)

Private Sub Form_Click() Dim x As Long, y As Long x = 200 y = 5 Print "x = "; x Print "y = "; y addLongs x, y 'If it reached this line, then its probably perfect. Print "Added y to x, so now x = "; x 'The answer better be 205, otherwise you stuffed something up! End Sub

A doua linie declar rutina care este folosit n VB. Trebuie fcute aceste declaraii pentru fiecare rutin pe care o folosii chiar dac ele sunt toate n acelai DLL. (Aici ea este declarat ca Private ceea ce inseamn c numai aceast form VB va putea s-o acceseze. Putei s-o punei ntr-un modul separat (.bas) astfel nct toate formele din proiectul dumneavoastr VB s-o poat accesa. n acest caz va trebui s eliminai cuvntul Private. Evident trebuie s schimbai directorul (relativ la directorul VB) pantru a arta unde este DLL-ul pe calculator, dac acesta este n alt parte. Rezultatul afiat trebuie s fie 205. Putei face aproape orice se poate face n DOS n DLL-ul creat cu excepia utilizrii ntreruperilor i trebuie inut cont c se programeaz n modul protejat. Dac nu ai programat niciodat n modul protejat asm nu v facei griji. Tot ce avei de fcut este s inei cont de faptul c segmentele nu sunt de 64k, ele sunt enorme i din acest motiv nu trebuie s utilizai dect un singur segment, acest lucru v permite accesul la megaoctei de memorie! (Windows lucreaz n modul protejat). Se pot face multe lucruri n DLL ce nu pot fcute nVB cum ar fi: o s v construii propriile rutine BitBlt sau StretchBlt o s scriei propriile rutine sistem DLL o utilizarea octetului inferior dintr-un ntreg o s folosii o locaie de memorie ca variabil o s folosii conversia ASCII a datelor binare sau n virgul mobil o sa realizai nmuliri sa mpriri prin deplasri o s optimizai codul pentru un anumit tip de calculator o s optimizai buclele o i multe altele

81

CAPITOLUL 3
PROGRAMAREA MICROPROCESORULUI TMS 320F240
Microprocesorul Texas Instruments TMS 320F240 posed un set complex de instruciuni, puternic i flexibil care permite utilizarea acestuia i ca procesor de semnal. Pentru programare se folosete cross-asamblorul TASM care permite obinerea fiierelor n cod obiect direct executabile, fiiere ce sunt transferate n memoria sistemului cu microcontroler TMS 320F2040 i lansate n execuie. Depanarea se face direct n sistem prin legtura ce se poate stabili prin interfaa serial sau prin intermediul dispozitivelor de tip JTAG.

3.1.

Setul de instruciuni a procesoarelor Texas Instruments C5X/C2XX

Categoriile de instruciuni: o instruciuni pentru folosirea acumulatorului i a memoriei; o instruciuni pentru Registrele Auxiliare i Poinerul pentru pagina de date; o instruciuni pentru registrul T, registrul P i nmulire; o instruciuni de salt i apel subprogram; o operaii I/O i cu memoria de date; o instruciuni de control; Tipuri individuale de instruciuni: ABS ADD ADDC ADDS ADDT ADRK AND APAC Valoarea absolut a acumulatorului; Adun cu acumulatorul; Adun cu acumulatorul i carry; Adun la partea inferioar a acumulatorului cu suprimarea extensiei de semn; Adun la partea superioar a acumulatorului cu deplasarea specificat n registrul T; Adunare imediat a registrului auxiliar cu valoare pe 8 bii; Operaie I cu acumulatorul; Adun registrul P cu acumulatorul; 82

APL B BACC BANZ BCND BIT BITT BLDD BLPD CALA CALL CC CLRC CMPL CMPR DMOV IDLE IN INTR LACC LACL LACT LAR LDP LPH LST LT LTA LTD LTP LTS MAC MACD MAR MPY MPYA MPYS MPYU NEG NMI NOP NORM OPL OR OUT

Operaie I cu dat din memorie cu DBMR (Dynamic Bit Manipulation Register) sau constant pe 16 bii; Salt necondiionat; Salt la locaia specificat de acumulator; Salt dac registrul auxiliar nu este zero; Salt condiionat; Test bit; Test bit specificat de registrul TREG2; Mutarea unui bloc din memoria de date n memoria de date; Mutarea unui bloc din memoria de program n memoria de date; Apelul unui subprogram din locaia specificat de acumulator; Apel necondiionat de subprogram; Apel condiionat de subprogram; terge bitul de control; Complementeaz acumulatorul; Compar registrul auxiliar cu registrul ARCR; ncarc o dat n memoria de date; Ateapt o ntrerupere; Citete o dat din port; ntrerupere software; ncarc acumulatorul cu deplasare; ncarc partea mai puin semnificativ a acumulatorului i terge partea mai semnificativ; ncarc acumulatorul cu deplasarea specificat de registrul TREG1 a datei ncrcate; ncarc registrul auxiliar; ncarc pointerul de pagin a memoriei de date; ncarc partea cea mai semnificativ a registrului P; ncarc registrul de stare; ncarc TREG0 ncarc TREG0 i adun produsul precedent; ncarc TREG0, adun produsul precedent i salveaz data; ncarc TREG0 i memoreaz registrul P n acumulator; ncarc TREG0 i scade produsul precedent; nmulete i adun; nmulete i adun cu salvarea datei; nmulete registrul auxiliar; nmulete (cu registrul T, memoreaz produsul n registrul P) nmulete i adun produsul precedent; nmulete i scade produsul precedent; nmulire fr semn; Neag acumulatorul; ntrerupere nemascabil; Nu execut nici o operaie; Normalizeaz coninutul acumulatorului; Operaia SAU cu DBMR sau cu data pe 16 bii; Operaia SAU cu acumulatorul; Trimitere dat la port; 83

PAC POP POPD PSHD PUSH RET RETC ROL ROR RPT SACH SACL SAR SBRK SETC SFL SFR SPAC SPH SPL SPLK SPM SQRA SQRS SST SUB SUBB SUBC SUBS SUBT TBLR TBLW TRAP XOR ZALR

ncarc acumulatorul cu registrul P register; ncarc din vrful stivei partea mai puin semnificativ a acumulatorului; ncarc din vrful stivei o dat n memorie; Depune din vrful stivei o dat din memorie; Depune partea mai puin semnificativ a acumulatorului n stiv; Rentoarcere din subprogram; Rentoarcere condiionat din subprogram; Rotete acumulatorul stnga; Rotete acumulatorul dreapta; Repet instruciunea urmtoare de un numr de ori specificat de o valoare din memoria de date; Salveaz partea mai semnificativ a acumulatorului cu deplasare; Salveaz partea mai puin semnificativ a acumulatorului; Salveaz registrul auxiliar; Scade din registrul auxiliar o dat pe 8 bii; Seteaz bitul de control; Deplaseaz acumulatorul stnga; Deplaseaz acumulatorul dreapta; Scade registrul P din acumulator; Salveaz partea cea mai semnificativ a registrului P; Salveaz partea cea mai puin semnificativ a registrului P Salveaz o valoare pe 16 bii; Seteaz modul de deplasare pentru registrul P; Ridic la ptrat i adun produsul precedent; Ridic la ptrat i scade produsul precedent; Salveaz registrul de stare; Scade din acumulator; Scade din acumulator cu mprumut; Scdere condiional; Scdere din partea mai puin semnificativ a acumulatorului, fr extensie de semn; Scdere din acumulator cu deplasare specificat de registrul T; Citire tabel; Scriere tabel; ntrerupere software; SAU exclusiv cu acumulatorul; Scrie zero n partea mai puin semnificativ a acumulatorului i ncarc partea mai semnificativ prin rotunjire.

Sintaxa instruciunilor INSTRUCIUNI REFERITOARE LA ACUMULATOR I MEMORIE ABS ADD ADDC ADDS ADDT AND CMPL LACC LACL NEGNORM OR ROL ROR SACH SACL SFL SFR SUB SUBB SUBC SUBS SUBT XOR ZALR ABS Absolute Value of Accumulator 84 LACT

ADD

ADDC ADDS ADDT AND Indirect: CMPL LACC

LACL

LACT NEG NORM OR

ROL ROR SACH

[label] ABS Add to Accumulator with Shift Direct: [label] ADD dma [,shift ] Indirect: [label] ADD {ind} [,shift [, next ARP]] Short Immediate:[label] ADD #k Long Immediate:[label] ADD #lk [,shift ] Add to Accumulator with Carry Direct: [label] ADDC dma Indirect: [label] ADDC {ind} [, next ARP] Add to Accumulator with Sign-Extension Suppressed Direct: [label] ADDS dma Indirect: [label] ADDS {ind} [, next ARP] Add to Accumulator with Shift Specified by T Register Direct: [label] ADDT dma Indirect: [label] ADDT {ind} [, next ARP] AND With Accumulator Direct: [label] AND dma [label] AND {ind} [, next ARP] Long Immediate:[label] AND #lk [, shift] Complement Accumulator [label] CMPL Load Accumulator With Shift Direct: [label] LACC dma, [,shift1 ] Indirect: [label] LACC {ind} [,shift1 [ next ARP]] Immediate:[label] LACC #lk [,shift2 ] where shift1 <= 16 and shift2 <= 15 Load Accumulator and Clear High Accumulator Direct: [label] LACL dma Indirect: [label] LACL {ind} [ ,next ARP] Immediate:[label] LACL #k Load Accumulator With Shift Specified by TREG1 Direct: [label] LACT dma Indirect: [label] LACT {ind} [ next ARP] Negate Accumulator [label] NEG Normalize Contents of Accumulator [label] NORM {ind} OR With Accumulator Direct: [label] OR dma Indirect: [label] OR {ind} [, next ARP] Long Immediate:[label] OR #lk [,shift ] Rotate Accumulator Left [label] ROL Rotate Accumulator Right [label] ROR Store High Accumulator With Shift Direct: [label] SACH dma 85

SACL SFL SFR SUB

SUBB SUBC SUBS SUBT XOR

ZALR

Indirect: [label] SACH {ind} [, next ARP] Store Low Accumulator With Shift Direct: [label] SACL dma Indirect: [label] SACL {ind} [, next ARP] Shift Accumulator Left [label] SFL Shift Accumulator Right [label] SFR Subtract from Accumulator with Shift Direct: [label] SUB dma [,shift1 ] Indirect: [label] SUB {ind} [,shift1 [, next ARP]] Short Immediate:[label] SUB #k Long Immediate:[label] SUB #lk [,shift2] Subtract from Accumulator with Borrow Direct: [label] SUBB dma Indirect: [label] SUBB {ind} [, next ARP] Conditional Subtract Direct: [label] SUBC dma Indirect: [label] SUBC {ind} [, next ARP] Subtract from Low Accumulator with Sign-Extension Suppressed Direct: [label] SUBS dma Indirect: [label] SUBS {ind} [, next ARP] Subtract from Accumulator with Shift Specified by TREG1 Direct: [label] SUBT dma Indirect: [label] SUBT {ind} [, next ARP] Exclusive-OR with Accumulator Direct: [label] XOR dma Indirect: [label] XOR {ind} [, next ARP] Long Immediate:[label] XOR #lk [,shift] Zero Low Accumulator and Load High Accumulator with Rounding Direct: [label] ZALR dma Indirect: [label] ZALR {ind} [, next ARP] LA REGISTRELE SBRK AUXILIARE I LA

INSTRUCIUNI REFERITOARE POINTERUL DE PAGIN ADRK ADRK CMPR LAR CMPR LAR LDP

MAR SAR

LDP

Add to Auxiliary Register Short Immediate [label] ADRK constant Compare Auxiliary Register with Auxiliary Register ARCR [label] CMPR constant Load Auxiliary Register Direct: [label] LAR AR, dma Indirect: [label] LAR AR, {ind} [, next ARP] Short Immediate:[label] LAR AR, #k Indirect: [label] LAR AR, #lk Load Data Memory Page Pointer 86

MAR SAR SBRK

Direct: [label] LDP dma Indirect: [label] LDP {ind} [, next ARP] Short Immediate:[label] LDP #k Modify Auxiliary Register Direct: [label] MAR dma Indirect: [label] MAR {ind} [, next ARP] Store Auxiliary Register Direct: [label] SAR AR, dma Indirect: [label] SAR AR, {ind} [, next ARP] Subtract From Auxiliary Register Short Immediate [label] SBRK #k

INSTRUCIUNI DE NMULIRE I REFERITOARE LA REGISTRELE T I P APAC LPH LT LTA LTD LTP MPY MPYU PAC SPAC SPH APAC LPH LT LTA LTD LTP LTS MAC MACD MPY LTS SPL MAC MACD MPY MPYA SPLK SPM SQRA SQRS

Add P Register to Accumulator [label] APAC Load Product High Register Direct: [label] LPH dma Indirect: [label] LPH {ind} [, next ARP] Load TREG0 Direct: [label] LT dma Indirect: [label] LT {ind} [, next ARP] Load TREG0 and Accumulate Previous Product Direct: [label] LTA dma Indirect: [label] LTA {ind} [, next ARP] Load TREG0, Accumulate Previous Product, and Move Data Direct: [label] LTD dma Indirect: [label] LTD {ind} [, next ARP] Load T Register and Store P Register in Accumulator Direct: [label] LTP dma Indirect: [label] LTP {ind} [, next ARP] Load TREG0 and Subtract Previous Product Direct: [label] LTS dma Indirect: [label] LTS {ind} [, next ARP] Multiply and Accumulate Direct: [label] MAC pma, dma Indirect: [label] MAC pma, {ind} [, next ARP] Multiply and Accumulate With Data Move Direct: [label] MACD pma, dma Indirect: [label] MACD pma, {ind} [, next ARP] Multiply Direct: [label] MPY dma Indirect: [label] MPY {ind} [, next ARP] Short Immediate:[label] MPY #k Long Immediate:[label] MPY #lk 87

MPYA MPYS MPYU PAC SPAC SPH SPL SPLK SPM SQRA SQRS

Multiply and Accumulate Previous Product Direct: [label] MPYA dma Indirect: [label] MPYA {ind} [, next ARP] Multiply and Subtract Previous Product Direct: [label] MPYS dma Indirect: [label] MPYS {ind} [, next ARP] Multiply Unsigned Direct: [label] MPYU dma Indirect: [label] MPYU {ind} [, next ARP] Load Accumulator with P Register [label] PAC Subtract P Register from Accumulator [label] SPAC Store High P Register Direct: [label] SPH dma Indirect: [label] SPH {ind} [, next ARP] Store Low P Register Direct: [label] SPL dma Indirect: [label] SPL {ind} [, next ARP] Store Parallel Long Immediate Direct: [label] SPLK #lk,dma Indirect: [label] SPLK #lk,{ind} [, next ARP] Set P Register Output Shift Mode [label] SPM constant Square and Accumulate Previous Product Direct: [label] SQRA dma Indirect: [label] SQRA {ind} [, next ARP] Square and Subtract Previous Product Direct: [label] SQRS dma Indirect: [label] SQRS {ind} [, next ARP]

IN STRUCIUNI DE SALT I APEL SUBPROGRAME B B[D] BACC[D] BANZ[D] BCND[D] BACC BANZ BCND CALA CALL CC RET RETC TRAP

Branch Unconditionally [label] B[D] pma [,{ind} [, next ARP]] Branch to Address Specified by Accumulator [label] BACC[D] Branch on Auxiliary Register Not Zero [label] BANZ[D] pma [,{ind} [, next ARP]] Branch Conditionally [label] BCND[D] pma [, cond1] [,cond2] [,..] Operands: 0 <= pma <= 65535 Conditions: ACC=0 EQ ACC != 0 NEQ ACC <0 LT ACC<= 0 LEQ 88

CALA[D] CALL[D] CC[D]

RET[D] RETC[D]

ACC > 0 GT ACC >=0 GEQ C=0 NC C=1 C OV=0 NOV OV=1 OV -BIO low BIO TC=0 NTC TC=1 TC Unconditionally UNC Call Subroutine Indirect [label] CALA[D] Call Subroutine [label] CALL[D] pma [,{ind} [, next ARP]] Call Conditionally [label] CC[D] pma [, cond1] [,cond2] [,..] Operands: 0 <= pma <= 65535 Conditions: ACC=0 EQ ACC != 0 NEQ ACC <0 LT ACC<= 0 LEQ ACC > 0 GT ACC >=0 GEQ C=0 NC C=1 C OV=0 NOV OV=1 OV -BIO low BIO TC=0 NTC TC=1 TC Unconditionally UNC Return From Subroutine [label] RET[D] Return From Subroutine Conditionally [label] RETC[D] [, cond1] [,cond2] [,..] Conditions: ACC=0 EQ ACC != 0 NEQ ACC <0 LT ACC<= 0 LEQ ACC > 0 GT ACC >=0 GEQ C=0 NC C=1 C OV=0 NOV OV=1 OV -BIO low BIO TC=0 NTC TC=1 TC 89

TRAP

Unconditionally UNC Software Interrupt [label] TRAP

OPERAII I/O I CU MEMORIA DE DATE APL BLDD BLPD CLRC DMOV IN OPL OUT SETC TBLR TBLW APL AND Data Memory Value with DBMR or Long Constant Direct: [label] APL [#lk,] dma Indirect: [label] APL [#lk,] {ind} [, next ARP] BLDD Block Move From Data Memory to Data Memory General Syntax: [label] BLDD src, dst All valid cases have the gereral syntax: Direct K/DMA: [label] BLDD #addr, dma Indirect K/DMA: [label] BLDD #addr, {ind} [, next ARP] Direct DMA/K: [label] BLDD dma,#addr Indirect DMA/K: [label] BLDD {ind} , #addr[, next ARP] Direct BMAR/DMA: [label] BLDD BMAR, dma Indirect BMAR/DMA: [label] BLDD BMAR, {ind} [, next ARP] Direct DMA/BMAR: [label] BLDD dma, BMAR Indirect DMA/BMAR:[label] BLDD {ind}, BMAR [, next ARP] BLPD Block Move From Program Memory to Data Memory General Syntax: [label] BLPD src, dst All valid cases have the general syntax: Direct K/DMA: [label] BLPD #pma, dma Indirect K/DMA: [label] BLPD #pma, {ind} [, next ARP] Direct BMAR/DMA: [label] BLPD BMAR, pma Indirect BMAR/DMA:[label] BLPD BMAR, {ind} [, next ARP] CLRC Clear Control Bit [label] CLR Ccontrol Bit Operands: STO, ST1 bit (from: { C, CNF, HM, INTM, OVM, TC, SXM, XF}) DMOV Data Move in Data Memory Direct: [label] DMOV dma Indirect: [label] DMOV {ind} [, next ARP] IN Input Data From Port Direct: [label] IN dma, PA Indirect: [label] IN {ind}, PA [, next ARP] OPL OR With DBMR or Long Immediate Direct: [label] OPL [.#lk,] dma Indirect: [label] OPL [.#lk,] {ind} [, next ARP] OUT Output Data to Port Direct: [label] OUT dma, PA Indirect: [label] OUT {ind}, PA [, next ARP] SETC Set Control Bit [label] SETC control bit 90

control bit: ST0 or ST1 bit (from:{C, CNF, HM, INTM, OVM, SXM, TC, XF}) TBLR Table Read Direct: [label] TBLR dma Indirect: [label] TBLR {ind} [, next ARP] TBLW Table Write Direct: [label] TBLW dma Indirect: [label] TBLW {ind} [, next ARP] INSTRUCIUNI DE CONTROL BIT BITT CLRC IDLE INTR LST NMI NOP POP POPD PSHD PUSH RPT SETC SST BIT BITT CLRC Test Bit Direct: [label] BIT dma, bit code Indirect: [label] BIT {ind}, bit code [, next ARP] Test Bit Specified by TREG2 Direct: [label] BITT dma Indirect: [label] BITT {ind} [, next ARP] Clear Control Bit [label] CLRC control bit Operands: STO, ST1 bit (from: { C, CNF, HM, INTM, OVM, TC, SXM, XF}) Idle Until Interrupt [label] IDLE Soft Interrupt [label] INTR k Load Status Register Direct: [label] LST #n, dma Indirect: [label] LST #n, {ind} [, next ARP] Nonmaskable Interrupt [label] NMI No Operation [label] NOP Pop Top of Stack to Low Accumulator [label] POP Pop Top of Stack to Data Memory Direct: [label] POPD dma Indirect: [label] POPD {ind} [, next ARP] Push Data Memory Value Onto Stack Direct: [label] PSHD dma Indirect: [label] PSHD {ind} [, next ARP] Push Low Accumulator Onto Stack [label] PUSH Repeat Instructions as Specified by Data Memory Value Direct: [label] RPT dma Indirect: [label] RPT {ind} [, next ARP] Short Immediate: [label] RPT #k 91

IDLE INTR LST NMI NOP POP POPD PSHD PUSH RPT

SETC

SST

Long Immediate: [label] RPT #lk Set Control Bit [label] SETC control bit control bit: ST0 or ST1 bit (from:{C, CNF, HM, INTM, OVM, SXM, TC, XF}) Store Status Register Direct: [label] SST #n, dma Indirect: [label] SST #n, {ind} [, next ARP]

NOT: n adresarea direct un cuvnt de instruciune conine cei mai puin semnificativi 7 bii ai adresei de memorie de date. Acest cmp este concatenat cu cei nou bii coninui de registrul pointerului la pagina memoriei de date (DP) obinndu-se 16 bii ai adresei memoriei de date. Rezult c n modul de adresare direct, memoria de date este paginat, coninnd n total 512 pagini, fiecare pagin coninnd 128 de cuvinte de 16 bii. Registrul DP poate fi modificat cu instruciunile LST i LDP. Adresarea indirect permite accesarea memoriei prin intermediul registrelor auxiliare. n acest mod de adresare, adresa operandului instruciunii este coninut de registrul auxiliar selectat. Exist opt regitrii auxiliari (AR0 AR7) care permit o adresare indirect flexibil i puternic. Pentru a selecta un anumit registru auxiliar, registrul pointer ARP este ncrcat cu o valoare de la zero la apte pentru indicarea registrului AR0, respectiv AR7.

3.2.

Turbo-Asamblorul (TASM)

Introducere TASM este un cross-asamblor pentru mediul MS-DOS. Realizeaz asamblarea codului surs scris ntr-un dialect adecvat (n general foarte apropiat de limbajul de asamblare al productorului). Codul obiect rezultat poate fi transferat microprocesorului prin intermediul memoriei PROM sau prin alte metode. Apelare TASM poate fi apelat astfel (cmpurile opionale sunt puse ntre paranteze ptrate iar cmpurile simbolice cu italice): tasm [-opiune] fiier_src [fiier_obiect [fiier_lst[fiier_exp[fiier_sym]]]] unde opiunea poate fi: o o o o o o o o o table -> opiune care specific versiunea tabelului de instruciuni folosit ttable -> tabel (alternativ la opiunea de mai sus) aamask -> controlul asamblrii (opiuni pentru verificarea erorilor) c -> fiierul obiect va fi scris ca un bloc continuu dmacro -> definete un macro (sau numai un nume de macro) e -> afieaz liniile surs dup expandarea macro fillbyte -> umple ntregul spaiu de memorie cu fillbyte (valoare hexa) i -> ignor literele mari n simboluri k -> genereaz fiiere obiect tip DSK 92

o o o o o o

l[al] -> creeaz tabelul etichetelor n listing p[lines] -> pagineaz fiierul listing (numrul de linii pe pagin implicit = 60) q -> dezactiveaz fiierul listing rkb -> seteaz dimensiunea buffer-ului de citire n koctei (implicit 2 koctei) s -> scrie un fiier cu tabela simbolurilor y -> timpul de asamblare

parametrii fiier sunt: fiier_src -> numele fiierului surs fiier_obj -> numele fiierului obiect fiier_lst -> numele fiierului listing fiier_exp -> numele fiierului de export (numai dac este utilizat directiva EXPORT) fiier_sym -> numele fiierului tabelei de simboluri (numai dac opiunea -s a fost utilizat sau s-au utilizat directivele SYM/AVSYM) Numele fiierului surs trebuie specificat obligatoriu. Dac nu se specific numele fiierului surs atunci se afieaz un help sumar. Implicit numele pentru celelalte fiiere (dac ele nu sunt specificate) sunt generate din numele fiierului surs la care se adaug extensia corespunztoare. Extensia folosit n acest caz este: Extensia .OBJ .LST .EXP .SYM Tip fiier Fiier obiect Fiier listing Fiier export simboluri Fiier tabel de simboluri

TASM nu are o tabel intern a setului de instruciuni pentru asamblare. Definirea instruciunilor se face prin citirea unui fiier la rularea TASM. TASM determin care este tabelul de instruciuni care va fi folosit din cmpul opiunii -table, care conine un numr zecimal de trei cifre, prezentat mai jos. De exemplu pentru a asambla codul din fiierul surs numit source.asm, trebuie s introducem comanda: tasm 203 source.asm (pentru limbaj de asamblare TMS320C2xx) Numele fiierului care conine tabela de instruciuni pentru exemplul de mai sus va fi: TASM203.TAB, deci n afar de numrul 203 prezent n opiune, numele fiierului este format prin adugarea n faa numrului TASM i extensia .TAB. Este posibil s proiectm tabele ale cror nume s conin litere i nume. De exemplu apelarea fiierului cu tabelul instruciunilor numit TASMF206.TAB se face cu comanda: tasm tf206 source.asm Fiecare opiune trebuie precedat de liniu (semnul minus). Numele fiierelor nu pot fi scrise n faa opiunilor. Descrierea opiunilor: 93

a controlul asamblrii TASM poate furniza o verificare suplimentar a erorii. Dac se specific -a fr nici o cifr dup aceea, atunci toate metodele de verificare sunt folosite. Dac se specific o cifr atunci se folosete o masc pentru a determina care verificare a erorilor se va face. Biii mtii sunt definii astfel: Bit 0 1 2 3 Opiune Descriere -a1 Verific utilizarea indirectrilor aparent ilegale -a2 Verific datele nefolosite n argumente -a4 Verific simbolurile multiple -a8 Verific operatorii non-unari la nceputul expresiei

Se pot folosi i combinaii ale biilor de mai sus. De exemplu -a5 va valida verificarea indirectrilor ilegale i a simbolurilor multiple. Indirectarea ilegal se aplic microprocesoarelor care folosesc parantezele n jurul unui argument pentru a indica indirectarea. Chiar dac este legal s punem nc un rnd de paranteze n jurul expresiei, TASM nu va accepta acest lucru dac nu este specificat clar n tabelul instruciunilor i dac verificarea respectiv este validat. Datele neutilizate dintr-un argument se aplic cazurilor cnd este nevoie n argument de un singur octet dar argumentul conine mai muli octei. O adres de 16 bii utilizat n adresarea imediat necesit un singur octet. Dac sunt folosii mai muli este generat un mesaj de eroare. Pentru ca aceste verificri s se fac ori de cte ori se lanseaz TASM, se adaug n AUTOEXEC.BAT linia: SET TASMOPTS = -a c scrierea ntr-un bloc continuu dac aceast opiune este specificat, atunci toi octeii de la primul la ultimul, din fiierul codului obiect, vor fi definii. n mod normal dac contorul de program (PC) sare mai departe pentru c s-a ntlnit o directiv .ORG, octeii srii nu vor avea nici o valoare atribuit (sunt ntr-o stare necunoscut) n fiierul obiect. Cu aceast opiune activat nu se scrie nimic n fiierul obiect nimic pn la sfritul asamblrii iar atunci se scrie ntregul bloc. Aceast opiune este folositoare atunci cnd generm cod care va fi pus n PROM i toi octeii trebuie s aib valori cunoscute. Aceast opiune se folosete n conjuncie cu opiunea -f pentru a ne asigura c toi octeii neutilizai vor avea o valoare cunoscut. d definirea unui macro macrourile sunt definite n liniile de comand ale fiierului surs pentru a asambla diferitele linii cu directiva IFDEF. Utilizarea opiunii este o cale convenabil pentru generarea diferitelor versiuni ale codului obiect dintr-un singur fiier surs. e expandarea sursei - n mod normal TASM afieaz numai liniile din fiierul surs. Dac se folosesc macrodefiniii (cu directive DEFINE), pentru a vedea liniile acestora n listing se folosete aceast opiune. f umplerea memoriei Tasm folosete o imagine a memoriei de 64 koctei chiar i atunci cnd procesorul nu poate folosi atta. Folosind opiunea -fxx atunci aceast imagine din memorie este umplut cu xxH. Sunt necesare aproximativ 2 secunde pentru iniializarea memoriei. i ignor literele mari din simboluri - n mod normal TASM face deosebire ntre literele mari i mici. Dac nu dorim acest lucru se folosete opiunea -i. 94

k genereaz format obiect DSK formatul obiect destinat utilizrii cu aplicaia Pathway 2xx DSK. l tabelul de simboluri genereaz un tabel al simbolurilor n fiierul listing. Simbolurile din macro nu sunt afiate. Dou sufixe pot fi utilizate opional cu opiunea -l. Sufix Descriere l utilizeaz forma lung a listingului a afieaz toate simbolurile (inclusiv cele locale) Sufixul se folosete imediat dup opiune. Exemple: -l -> afieaz simbolurile nelocale n forma scurt; -la -> afieaz toate simbolurile n forma scurt; -ll -> afieaz simbolurile nelocale n forma lung; -lal -> afieaz toate simbolurile n forma lung. p paginarea fiierului listing aceast opiune determin ca fiierul listing s aib un antet i un subsol dup fiecare grup de 60 de linii. Dac dorim alt numr de linii pe pagin atunci acest lucru se d explicit. Exemplu: TASM 203 p56 source.asm q dezactiveaz fiierul listing aceast opiune suprim fiierul listing chiar dac s-a ntlnit o directiv .LIST. r seteaz dimensiunea bufferului de citire aceast opiune modific dimensiunea implicit (2 koctei) a bufferului de citire. Dup r urmeaz o cifr hexazecimal care d dimensiunea bufferului (exemplu: -r8 indic un buffer de 8 koctei iar -rf indic un buffer de 15 koctei). Trebuie notat c bufferul de citire ocup aceeai zon de memorie ca simbolurile i macro. De obicei creterea bufferului de citire este necesar dac sunt utilizate directive INCLUDE. Dimensiunea de 8 koctei de buffer poate fi suficient pentru cele mai multe asamblri dar programele cu multe simboluri pot s nu permit aceast valoare. De altfel reducnd bufferul la 1 koctet se poate crete memoria disponibil pentru stocarea simbolurilor (dac acest lucru este necesar). s valideaz generarea fiierului de simboluri dac aceast opiune este setat atunci va fi generat un fiier de simboluri la sfritul asamblrii. Formatul acestui fiier este: un simbol pe linie, fiecare simbol ncepnd n prima coloan i este urmat de un blanc i patru valori hexa reprezentnd valoarea simbolului. Exemplu: label1 FFFE label2 FFFF label3 1000 Fiierul de simboluri poate fi generat i de directiva SYM. t numele tabelei variant alternativ pentru a specifica tabela de instruciuni. Aceast opiune este folositoare cnd tabelul ncepe cu un caracter nezecimal. De exemplu tabelul F8 poate fi selectat astfel: TASM tf8 source.asm Se va citi tabelul de instruciuni din fiierul: TASMF8.TAB y valideaz msurarea timpului de asamblare dac opiunea este validat se va genera timpul de asamblare i numrul de linii asamblate/secund la sfritul asamblrii. 95

Variabilele de mediu Mediul TASM poate fi personalizat utiliznd urmtoarele variabile de mediu: TASMTABS specific calea de cutare pentru tabelele cu instruciuni destinate TASM Exemplu: SET TASMTABS = C:\TASM dac tabela de instruciuni se gsete n directorul TASM TASMOPTS opiunile ce se vor folosi la execuia TASM Exemplu: SET TASMOPTS = -203 k Codurile de ieire Cod ieire 0 1 2 3 4 Semnificaie Terminare normal, fr erori de asamblare Terminare normal, cu erori de asamblare Terminare anormal, memorie insuficient Terminare anormal, eroare la acces fiier Terminare anormal, eroare general

Codul de ieire 2 este nsoit de mesajele de eroare la consol. Formatul fiierului surs Structura general: etichet operaie operand comentariu toate cmpurile sunt opionale. Cmpurile sunt separate de unul sau mai multe spaii sau TAB. Lungimea maxim a liniei are 255 caractere. Cmpul etichet - dac primul caracter al liniei este alfabetic atunci se consider nceputul etichetei. Caracterele care urmeaz sunt considerate ca aparinnd etichetei cu excepia caracterului spaiu, TAB sau : cnd se consider c este sfritul etichetei. Lungimea maxim a etichetei este de 32 de caractere. n mod normal etichetele difer ntre ele dac se folosesc caractere mari i mici (cu excepia cazului cnd se folosete opiunea -i). Cmpul operaiei conine un mnemonic. Poate ncepe n orice coloan cu excepia primei coloane. Nu are importan dac se folosesc litere mari sau mici. Cmpul operandului poate include expresii i/sau simboluri speciale ce descriu modul de adresare utilizat. Cmpul comentariu - ncepe cu caracterul ; restul caracterelor dup acesta fiind ignorat de TASM Linii cu mai multe comenzi mai multe instruciuni pot fi scrise pe o linie separate cu \ (backslash). Prima coloan dup \ este considerat coloana 1 a noii instruciuni i deci aici va fi eticheta (dac exist). Acest mod de scriere este folositor la construcia macro.

96

Expresii Expresiile pot fi construite cu mai multe elemente: 1. simboluri 2. constante 3. simbolul contorului de locaii 4. operatori 5. paranteze Simboluri reprezint valori numerice. Simbolurile locale ncep cu o liter sau cu prefixul implicit al simbolurilor locale _. Valoarea simbolului este limitat la precizia de 32 de bii (32 caractere). Constantele numerice - ncep cu un numr. Cele hexa trebuie s nceap cu 0 dac prima cifr este o liter. Aceast condiie nu este necesar dac se folosete n faa cifrei hexa simbolul $. Baza de numeraie este stabilit de prefixul sau sufixul numrului. Baza de numeraie 2 8 10 16 Sufix B sau b O sau o D sau d H sau h Prefix % @ nimic $

Prefixele pot introduce ambiguiti. Simbolurile % i $ au utilizri alternative: % pentru operaia modulo i $ pentru simbolul contorului de locaii. Ambiguitatea este rezolvat studiind contextul. Caracterul % este interpretat ca modulo numai dac este n poziia necesar pentru un operator binar. La fel dac dup $ este un caracter hexa valid atunci se consider numr hexa, altfel se consider contor de locaii. Constantele caracter sunt caractere unice ntre ghilimele (ghilimelele de la sfrit sunt opionale). Aceste constante reprezint valoarea ASCII a caracterului. Caracterele netipribile nu pot fi folosite. Constantele ir sunt constante formate din unul sau mai multe caractere ntre ghilimele. Constantele ir nu sunt permise n expresii. Ele pot fi folosite numai n directivele asamblor TITLE, BYTE i TEXT. Caracterele netipribile permise aici sunt: Caracter netipribil \n \r \b \t \f \\ \ \ooo Descriere Linie nou Retur de car Un caracter la stnga (backspace) TAB Formfeed Backslash Ghilimele Valoarea octal a caracterului de tiprit 97

Simbolul contorului de locaii valoarea curent a contorului de program PC poate fi folosit n expresii utiliznd simbolul $. Se poate folosi orinde sunt permise i constantele numerice. Dac este urmat de o cifr hexa atunci simbolul se va considera constant hexa. Se poate folosi i simbolul * dar acesta nu este preferat din cauza ambiguitii cu operatorul de nmulire. Operatorii operatorii posibil de utilizat n expresii sunt: Operator + * / % << >> ~ = == != < > <= >= & | ^ Tip Aditiv Multiplicativ Descriere adunare scdere nmulire mprire modulo rotaie logic stnga rotaie logic dreapta inversarea bitului (complement fa de 1) negaie unar egal egal diferit mai mic mai mare mai mic sau egal mai mare sau egal I binar SAU binar SAU EXCLUSIV binar

Unar Relaional

Binar

Sintaxa este similar cu cea din limbajul C cu urmtoarele observaii: 1. Precedarea operatorului nu are efect. Evaluarea se face de la stnga la dreapta cu excepia gruprii n paranteze. 2. Toate evalurile se fac pe 32 de bii cu semn. 3. Ambii operatori = i = = se pot folosi pentru verificarea egalitii. Operatorii relaionali ntorc valoarea 1 dac relaia este adevrat i valoarea 0 dac este fals. Sunt folosii 32 de bii cu semn. Este bine s se indice ordinea operaiilor cu paranteze pentru a pstra portabilitatea din cauz c TASM nu evalueaz operaiile ca alte asambloare. Exemplu: 1+2*3+4 va fi evaluat de TASM astfel: (((1+2)*3)+4)=13 regulile tipice de preceden impun evaluarea lui (2*3) mai nti, astfel: 98

1+(2*3)+4=11 Pentru a fi siguri c se obine ordinea dorit de evaluare a operaiilor folosii parantezele ct mai mult. Exemple de expresii valide: (0f800H+tab) (label_2 >> 8) (label_3 << 8) & $f000 $+4 010010000100100b +a (base + ((label_4 >> 5) & (mask << 2)) Directivele asamblorului Cele mai multe directive asamblor au un format similar cu instruciunile main. Exist dou tipuri de directive de asamblare unele care se aseamn cu funciile preprocesor din limbajul C i altele care se aseamn mai mult cu directivele tradiionale asamblor. Directivele de tip preprocesor C sunt invocate cu # n primul caracter al liniei urmat de directiv (exact ca n limbajul C). Sunt acceptate att caracterele mari ct i cele mici. ADDINSTR poate fi utilizat pentru a defini o instruciune suplimentar pentru a fi folosit la asamblarea cu TASM. Formatul este: [etichet] .ADDINSTR inst args opcode nbytes modop class shift binar cmpurile sunt separate cu spaii exact cum trebuie s apar n fiierul de definiii a instruciunii. LOCK aceast directiv duce la avansarea contorului de instruciuni cu un numr specificat de octei fr atribuirea vreunei valori locaiilor srite. Formatul este: [etichet] .BLOCK expr Exemple: word1 .BLOK 2 byte1 .BLOK 1 buffer .BLOK 80 BYTE este folosit la atribuirea unei valori adresate de contorul de locaii (locaia curent). Formatul este: [etichet] .BYTE expr[,expr ...] Numai octetul cel mai puin semnificativ al expresiei este folosit. Exemple: label1 .BYTE 10010110B .byte a .byte 0 .byte 100010110b,a,0 .byte Hello,10,13,World CHK determin calculul unei sume de control care va fi depus n locaia curent. Punctul de nceput al sumei de control este dat n argument. Formatul este: .CHK start_addr 99

Suma de control este calculat ca o sum aritmetic simpl ncepnd de la start_addr pn la adresa (exclusiv) a directivei CHK. Cel mai puin semnificativ octet este memorat. CODES/NOCODES se folosete pentru a comuta succesiv generarea codului n fiierul de ieire. Cu NOCODES activat liniile surs sunt trimise n listingul de ieire fr a se genera cod. Este util pentru comentariile lungi. DB este o alternativ a directivei BYTE. DW este o alternativ a directivei WORD. DEFINE este una din cele mai puternice directive care permite substituia unor iruri cu argumente opionale (macro). Formatul este urmtorul: #DEFINE macro_label [(arg_list)] [macro_definition] macro_label := irul care va fi expandat cnd este gsit n fiierul surs arg_list := ir opional cu variabile pentru substituia variabilelor din macro macro_def := irul care apare n locul macro_label n textul surs Exemplu: #DEFINE MLABEL Notai c nu s-a specificat irul de substituie. Scopul unei directive de acest fel este n mod tipic de a defini o variabil n scopul controlului unor secvene de asamblare condiionat (IFDEF sau IFNDEF). Un alt exemplu: # DEFINE VAR1_LO (VAR1 & 255) Aceast instruciune va determina nlocuirea irului VAR1_LO din programul surs cu (VAR1 & 255) Reguli asociate cu lista de argumente: 1. Utilizai maximum 10 argumente 2. Fiecare argument trebuie s aib maximum 15 caractere. De notat c aceste macro pot fi definite de asemenea n linia de comand TASM, utiliznd opiunea -d. DEFCONT se utilizeaz pentru a aduga linii la ultimul macro nceput cu o directiv DEFINE. Furnizeaz o metod convenabil de a defini macrouri lungi care depesc o linie. Exemplu: #DEFINE ADD (xx,yy) clc #DEFCONT \lda xx #DEFCONT \ldc yy #DEFCONT \sta xx DS aceast directiv se comport similar cu directiva .ORG. Poate fi utilizat pentru a identifica adresa unde vor fi plasate datele n Spaiul de Date a lui TMS320C2xx. EJECT schimbarea paginii i generarea unui header n fiierul de listare. Nu are efect dac modul de paginare este dezactivat (PAGE/NOPAGE). Formatul: .EJECT ELSE se utilizeaz opional cu IFDEF, IFNDEF i IF pentru a desemna un bloc alternativ de asamblat n cazul n care blocul imediat dup IFDEF, IFNDEF i IF nu este asamblat. 100

Exemple: #IFDEF label1 lda byte1 sta byte2 #ENDIF #ifdef label1 lda byte1 #else lda byte2 #endif #ifndef label1 lda byte2 #else lda byte1 #endif #if ($>=100h) ;genereaz o instruciune invalid pentru a produce o eroare atunci ;cnd depim ;grania de 4k octei #endif END aceast directiv trebuie s fie ultima n fiierul surs. Foreaz scrierea ultimei nregistrri n fiierul obiect. Format: [label] .END ENDIF aceast directiv trebuie s urmeze ntotdeauna dup o directiv IFDEF, IFNDEF sau IF i semnific sfritul blocului condiional. ENTRY este utilizat pentru identificarea punctului de intrare (punct de start) n Spaiul de Program a programului pentru TMS320C2xx. Exemplu: .ps 8000h ;poziionare PC .entry ;definete punctul de intrare n program start: nop ;aceast instruciune va fi punctul de intrare EQU este folosit pentru a atribui o valoare unei variabile. n aceast situaie variabilele pot fi folosite n expresii drept constante literale. Format: etichet .EQU expr Exemplu: MASK .EQU 0F0H ; lda IN_BYTE and MASK sta OUT_BYTE O form alternativ a lui EQU este =. Exemplul anterior este echivalent cu: 101

MASK = $F0 sau MASK =0F0H sau MASK = $F0 Este necesar un spaiu dup denumire dar nu neaprat dup =. EXPORT este folosit pentru a scrie simbolurile ntr-un fiier de ieire. Numele fiierului de ieire este dat de opiunea -s. Simbolurile sunt scrise ca egaliti (utiliznd directive .EQU) fiierul rezultat putnd fi inclus ntr-o asamblare subsecvenial. Aceast facilitate poate ajuta la eliminarea unor deficiene ale TASM date de linkeditor. Format: [etichet] .EXPORT etichet Exemplu: Fiierul surs: .EXPORT read_byte .EXPORT write_byte .EXPORT open_file Fiierul rezultat: read_byte .EQU $1243 write_byte .EQU $12AF open_file .EQU $1301 IFDEF folosit pentru asamblarea opional a unui bloc de instruciuni. Forma: #IFDEF macro_label Cnd este apelat, lista de macro_labels (stabilite pe baza directivelor DEFINE) sunt cutate. Dac eticheta este gsit, n fiierul de intrare sunt srite liniile de dup IFDEF pn este ntlnit o directiv ENDIF sau ELSE. Liniile srite apar totui n fiierul listing dar semnul ca aprea imediat dup PC curent i nu se genereaz cod obiect (acest lucru este aplicabil i la directivele IFDEF, IFNDEF i IF). IFNDEF este opusa directivei IFDEF. Blocul de instruciuni urmtor directivei este asamblat numai dac macro_label nu este definit. Forma: # IFNDEF macro_label Cnd este apelat, lista de macro_labels (stabilite pe baza directivelor DEFINE) sunt cutate. Dac eticheta nu este gsit, n fiierul de intrare sunt asamblate liniile de dup IFNDEF pn este ntlnit o directiv ENDIF sau ELSE. IF este utilizat pentru asamblarea opional a unui bloc de instruciuni n funcie de valoarea dat de expresie. Format: #IF expr Dac expresia evaluat este diferit de zero blocul urmtor directivei IF este asamblat (pn se ntlnete o directiv ENDIF sau ELSE).

102

INCLUDE citete i asambleaz fiierul surs indicat. Directiva poate avea pn la ase nivele. Permite o cale convenabil de pstrare a definiiilor comune, declaraiilor sau subprogramelor. Format: #INCLUDE nume_fiier Numele fiierului trebuie inclus ntre ghilimele duble. Exemple: #INCLUDE macros.h #include equates #include subs.asm LIST/NOLIST aceste directive pot fi folosite alternativ pentru a lista sau a suprima listarea n fiierul listing. Format: .LIST .NOLIST ORG seteaz contorul de instruciuni (contorul de program PC) la valoarea dorit. Format: [etichet] .ORG expr Exemplu: Pentru a genera cod ncepnd cu adresa 1000H: start .ORG 1000H Expresia poate conine referiri la valoarea curent a pointerului de instruciuni permind diferite manipulri de date. De exemplu pentru a alinia pointerul de instruciuni peste 256 de octei se poate folosi: ORG (($+0FFH) & 0FF00H) Directiva ORG poate fi folosit de asemenea pentru a rezerva spaiu fr a desemna valoarea: .ORG $+8 O form alternativ a directivei ORG este *= sau $=. Exemplul anterior este echivalent cu: *=*+8 $=$+8 PAGE/NOPAGE este folosit pentru listarea n mod pagin sau continuu. Format: .PAGE .NOPAGE PS se comport ca i directiva .ORG. Se folosete pentru poziionarea contorului de program n Spaiul Program a lui TMS320C2xx. SET permite schimbarea valorii unei variabile existente. Format: variabil .SET expresie Utilizarea directivei SET trebuie evitat pentru c ea poate duce la erori de faz ntre pasul 1 i pasul 2 a asamblrii. SYM directiva poate fi utilizat pentru a genera un fiier cu tabela simbolurilor. Formatul: .SYM [fisier_simboluri] Exemplu: .SYM symbol.map 103

.SYM Formatul fiierului SYM este de un simbol pe linie, fiecare simbol ncepe n prima coloan este urmat de un spaiu i apoi patru cifre hexa reprezentnd valoarea simbolului. Exemplu de format: label1 FFFE label2 FFFF label3 1000 TEXT permite folosirea unui ir ASCII cruia i se va aloca adresa curent a pointerului de instruciuni. Formatul este: [etichet] .TEXT ir Valoarea ASCII a fiecrui caracter din ir este atribuit locaiei urmtoare n mod succesiv. Sunt admise secvene speciale: Caracter netipribil Descriere \n \r \b \t \f \\ \ \ooo Exemple: message1 message2 Linie nou Retur de car Un caracter la stnga (backspace) TAB Formfeed Backslash Ghilimele Valoarea octal a caracterului de tiprit

.TEXT Disk I/O error .text Enter file name .text abcdefg\n\r .text I said \NO\ TITLE se folosete pentru definirea unui titlu de ctre utilizator care va aprea la nceputul fiecrei pagini (dac este activ PAGE). Formatul: .TITLE string irul nu trebuie s depeasc 80 de caractere. Exemple: .TITLE Controller version 1.1 .title This is the title of the assembly .title WORD permite atribuirea unei valori urmtoarelor dou locaii ncepnd de la valoarea curent a pointerului de instruciuni. Formatul: [etichet] .WORD expr Cel mai puin semnificativ octet este pus primul i dup aceea cel mai semnificativ (cu excepia cazului cnd se folosete directive MSFIRST). Exemple: data_table .WORD (data_table+1) .word $1234 104

.Word .Word Formatul fiierului obiect

((x-a) << 2) 12,55,32

TASM poate genera fiiere obiect care pot fi ncrcate n Pathway 2xx DSK. Acest format este orientat pe linii i utilizeaz numai caractere ASCII tipribile cu excepia returului de car de la sfritul fiecrei linii. Sunt trei tipuri diferite de linii pentru formatul DSK. Primul tip de linie n format DSK conine numai informaiile header inclusiv numele fiierului. De exemplu: K_D203_1.01_xf.dsk Urmtoarea linie conine informaii despre punctul de intrare pentru program i semnaleaz acest lucru ncepnd linia cu caracterul 1. De exemplu: FE078FE0F n acest format pentru punctul de intrare, informaiile sunt urmtoarele: 1 ncepe linia i indic faptul c aceast linie conine informaii legate de punctul de intrare. Urmtoarele patru caractere, n acest caz 8FE0, indic adresa hexa a punctului de intrare a programului. Caracterul 7 care urmeaz dup adres este un separator i indic faptul c urmeaz suma de control pe patru caractere. n sfrit caracterul F indic faptul c linia s-a terminat i urmeaz retur de car i linie nou. Ultimul tip de linie n format obiect DSK este linia care conine programul/datele rezultate n urma asamblrii. Formatul este prezentat n continuare. Fiecare linie ncepe cu caracterul 9. Urmtoarele patru caractere reprezint adresa hexa unde sunt plasate codul/datele. Urmeaz un caracter cu rol de separator. Dac acest caracter este M acest lucru arat c urmtoarele patru caractere hexa sunt date care vor fi ncrcate n Spaiul de Date a dispozitivului 2xx. Dac separatorul este B acest lucru arat c urmtoarele patru caractere hexa trebuie ncrcate n Spaiul de Program a dispozitivului 2xx. Separatorul se repet pn se ntlnete caracterul 7 n locul separatorului. Dup caracterul 7 ca separator urmeaz o sum de control hexa de patru caractere. n sfrit caracterul F indic faptul c urmeaz retur de car i linie nou. Iat dou exemple: 90300MBABEMDEADMB00B74976F 98FE0BBC04BBF0AB0000BBF0B7BE89F Caracterul folosit pentru a indica sfritul fiierului de cod obiect este :. Mesajele de eroare Mesajul de eroare Binary operator where value expected Cannot malloc for label storage Duplicate label Descriere S-au ntlnit doi operatori binari unul dup cellalt fr o valoare ntre ei (lipsete valoarea) Memorie insuficient pentru stocarea simbolurilor (vezi LIMIT|RI) Verificarea simbolurilor multiple validat prin opiunea -a 105

Filename too short

Heap overflow on label definition Invalid operand

Invalid token where value expected Label too long Label value misaligned

Label not found Label must pre-exist for SET Label table overflow List file open error Macro expansion too long Maximum number of macros exceeded No END directive before EOF No files specified

Numele fiierului din linia de comand are mai puin de trei caractere. Aceast limitare este impus pentru a nu confunda o opiune cu numele unui fiier. TASM nu poate aloca memorie pentru a stoca variabile Nu exist indirectare pentru aceast instruciune. Primul caracter a unui operand este o parantez stng pentru instruciunile care nu specific explicit acest format. Unele micro utilizeaz parantezele pentru a semnala indirectarea dar punerea unei perechi de paranteze la o expresie este un lucru valabil (cu att mai mult cu ct intereseaz evaluarea expresiei). Testul n acest caz este dat numai dac opiunea a4 este selectat (vezi seciunea CONTROLUL ASAMBL|RII) Doi operatori binari unul dup cellalt nu sunt permii Etichetele sunt limitate la 31 de caractere Valoarea simbolului pare a avea o valoare diferit n cel de-al doilea pas fa de cea calculat n primul pas. Acest lucru este dat n general de modul de adresare n pagina zero la versiunea TASM 6502. Simbolurile care sunt utilizate ca operanzi n instruciuni nu pot fi utilizate pentru modul de adresare n pagina zero. Modul de adresare n pagina zero trebuie ntotdeauna definit nainte de a fi utilizat ca operand. Un simbol utilizat ntr-o expresie nu este gsit n tabela de simboluri Directiva SET nu poate fi aplicat dect unui simbol existent S-au ntlnit prea multe simboluri TASM nu poate deschide fiierul specificat Expresia macro rezultat ntr-o linie depete lungimea maxim S-au ntlnit prea multe directive DEFINE Fiierul surs nu conine directive END. Nu e critic dar s-ar putea ca n fiierul obiect ultima nregistrare s se piard TASM a fost apelat fr specificarea fiierului surs 106

No such label yet defined No indirection for this instruction Non-unary operator at start of expresion

Object file open error Range of argument exceeded Range of relative branch exceeded Source file open error Unrecognized directive Unrecognized instruction Unrecognized argument Unknown token Unused data in MS byte of argument

Unknown option Flag

O directiv SET a fost ntlnit pentru o variabil care nu a fost nc definit S-a folosit o expresie ntre paranteze. Acest lucru poate nsemna o ncercare de indirectare ntr-un loc nepotrivit Un operator binar (ca de exemplu *) a fost gsit la nceputul expresiei. Unele micro utilizeaz * ca operator de indirectare. Chiar dac este un operator legitim n expresie, pot aprea ambiguiti. Dac un mod particular de instruciune/adresare nu permite indirectarea i un * este plasat n faa expresiei asociate, asamblorul va semnala aceast eroare. Vezi opiunea -a8 n CONTROLUL ASAMBL|RII. TASM nu poate deschide fiierul obiect specificat Valoarea unui argument depete domeniul valid pentru modul de adresare al instruciunii curente O instruciune de salt depete domeniul maxim TASM nu poate deschide fiierul surs specificat O instruciune care ncepe cu . sau # are un mnemonic care nu este definit ca directiv O instruciune are un cod operaie care nu este definit O instruciune are un operand care nu e definit A fost gsit un caracter nepotrivit la analiza unei expresii O instruciune sau o directiv utilizeaz cel mai puin semnificativ octet al unui argument i pierde cel mai semnificativ octet dar acesta nu este zero Invalid option flag has been specified on the command line. Apelai TASM fr nici o opiune n linia de comand pentru a vedea opiunile valide.

Erori i limitri Limitri i specificaii Numrul maxim de simboluri Lungimea maxim a simbolurilor Spaiul maxim de adresare 107 2000 32 caractere 64 koctei (65536 octei)

Numrul maxim de directive INCLUDES imbricate Lungimea maxim a titlului Lungimea maxim a liniei surs Lungimea maxim dup expandarea macro Lungimea maxim a expresiilor Lungimea maxim a cilor de cutare Lungimea maxim a liniei de comand Numrul maxim de instruciuni (pe tabel) Numrul maxim de macro Numrul maxim de argumente ale macro Lungimea maxim a argumentului macro Dimensiunea Heap (pt. simboluri, macro i buffere) Necesar de memorie Erori

4 79 caractere 255 caractere 255 caractere 255 caractere 79 caractere 127 caractere 600 1000 10 16 caractere 20000 octei 160K

1. Expresiile nu au prioriti la execuie i deci rezultatul poate fi imprevizibil dac nu se utilizeaz parantezele pentru a stabili ordinea de calcul. 2. Prima pagin din listing nu va arta titlul definit de utilizator (definit prin directive TITLE). 3. TASM nu va genera mesaje de eroare pentru expresii formate incorect.

3.3.

Exemple de programe n limbaj de asamblare, pentru microprocesorul TMS 320F240

n aceast seciune vor fi prezentate programe demonstrative care s ilustreze modul de programare a unitii centrale DSP TMS320F240, Texas Instruments. Programele au fost realizate cu ajutorul sistemul de dezvoltare al firmei White Mountain, DSP (WMDSP) Pathway 24x. PROGRAMUL 1. Este un program simplu care s arate care este structura general a unui program scris n limbaj de asamblare.
;Acest program este realizat pentru a testa elementele limbajului de asamblare ;In program se aduna la o locatie 40h pentru a genera un semnal rampa .nolist .include "..\\..\\..\\include\\pathway.inc"

;tabela de intreruperi ;nu folosesc deocamdata intreruperile dar tabela trebuie initializata .ps 0fe00h b b b b b b b b 0000h Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR ; starting address for this section is ; 0fe00h in Program Space (CNF = 1) ; (00h) Hardware Reset ; (02h) Interrupt Level 1 ; (04h) Interrupt Level 2 ; (06h) Interrupt Level 3 ; (08h) Interrupt Level 4 ; (0Ah) Interrupt Level 5 ; (0Ch) Interrupt Level 6 ; (0Eh) Reserved

108

b b b b b b b b b b b b b b b b b b b b b b b b .list ;programul principal inceput_memorie .EQU 310h sfarsit_memorie .EQU 330h ;definesc o variabila temporara .ds 300h temp .word 0 .ps 0fe50h .entry

Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR

; (10h) User-defined Software Interrupt ; (12h) User-defined Software Interrupt ; (14h) User-defined Software Interrupt ; (16h) User-defined Software Interrupt ; (18h) User-defined Software Interrupt ; (1Ah) User-defined Software Interrupt ; (1Ch) User-defined Software Interrupt ; (1Eh) User-defined Software Interrupt ; (20h) User-defined Software Interrupt ; (22h) TRAP instruction vector ; (24h) Nonmaskable interrupt (NMI) ; (26h) Reserved ; (28h) User-defined Software Interrupt ; (2Ah) User-defined Software Interrupt ; (2Ch) User-defined Software Interrupt ; (2Eh) User-defined Software Interrupt ; (30h) User-defined Software Interrupt ; (32h) User-defined Software Interrupt ; (34h) User-defined Software Interrupt ; (36h) User-defined Software Interrupt ; (38h) User-defined Software Interrupt ; (3Ah) User-defined Software Interrupt ; (3Ch) User-defined Software Interrupt ; (3Eh) User-defined Software Interrupt

;initializari ;initializez registrul de pagina din memoria de date ;initializez registrele cu zona de memorie unde scriu datele ldp #06h ;registrul de pagina din Memoria Date lar ar0,#sfarsit_memorie ;adresa maxima de memorie lar ar1,#inceput_memorie ;adresa de inceput mar *,ar1 ;registrul ar5 este cel curent ;prima varianta ;Bucla: ; ; ; ; ;

lacl temp add #40h sacl temp b Bucla

;incarc acululatorul cu continutul memoriei ;adun 40h ;memorez rezultatul ;continui

;varianta a doua mai perfectionata splk #0,* ;stochez la adresa AR5 valoarea 0 bucla: lacl #40h ;incarc acumulatorul cu 40h add *+ ;adun la acumulator valoarea adresata de AR5 si incrementez AR5 cmpr 2 ;verific daca nu s-a depasit zona de memorie alocata bcnd cont,NTC ;daca nu s-a depasit, continui lar ar1,#inceput_memorie ;o iau de la capat

109

lacl #0 cont: sacl * b bucla Phantom_ISR:

;incarc acumulatorul cu zero ca s-o ia de la capat ;stochez noua valoare ;continui b Phantom_ISR

.end

PROGRAMUL 2. Testarea conversiei analog numerice.


;Acest program este demonstrativ pentru utilizarea ADC ;Citirile se fac simultan pe cele doua ADC pe intrarea analogica ADCIN7 (pin 35 conector ;P13 MC-BUS primary Pathway) pentru ADC1 si pe intrarea analogica ADCIN15 (pin 36 conector ;P13 MC-BUS primary Pathway) pentru ADC2 ;Intreruperile se genereaza cu ADC la sfarsitul conversiei. ;Pornirea conversiei se face pe eveniment GPT 1 la atingerea perioadei ;Citirile se fac la atingerea perioadei de 0.625ms (32 esantioane/perioada) ;Numaratorul GPT1 are factor de prescalare 1 si este incarcat in numarator cu 12499 ;Timp = 12500/20 000 000= 0.625ms ;----------------.nolist .include ;tabela de intreruperi .ps 0fe00h b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b 0000h Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Intr_ADC Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR ; starting address for this section is ; 0fe00h in Program Space (CNF = 1) ; (00h) Hardware Reset ; (02h) Interrupt Level 1 ; (04h) Interrupt Level 2 ; (06h) Interrupt Level 3 ; (08h) Interrupt Level 4 ; (0Ah) Interrupt Level 5 ; (0Ch) Interrupt Level 6 (Intrerupere ADC) ; (0Eh) Reserved ; (10h) User-defined Software Interrupt ; (12h) User-defined Software Interrupt ; (14h) User-defined Software Interrupt ; (16h) User-defined Software Interrupt ; (18h) User-defined Software Interrupt ; (1Ah) User-defined Software Interrupt ; (1Ch) User-defined Software Interrupt ; (1Eh) User-defined Software Interrupt ; (20h) User-defined Software Interrupt ; (22h) TRAP instruction vector ; (24h) Nonmaskable interrupt (NMI) ; (26h) Reserved ; (28h) User-defined Software Interrupt ; (2Ah) User-defined Software Interrupt ; (2Ch) User-defined Software Interrupt ; (2Eh) User-defined Software Interrupt ; (30h) User-defined Software Interrupt ; (32h) User-defined Software Interrupt ; (34h) User-defined Software Interrupt ; (36h) User-defined Software Interrupt ; (38h) User-defined Software Interrupt ; (3Ah) User-defined Software Interrupt ; (3Ch) User-defined Software Interrupt

"..\\..\\..\\include\\pathway.inc"

110

b .list ;datele sfarsit_memorare ;programul principal .ps 0fe50h .entry start: setc clrc INTM sxm

Phantom_ISR

; (3Eh) User-defined Software Interrupt

.ds 300h .word 0 ;aici se scrie 1 cand s-a umplut zona 310h-350h

; adresa de inceput a programului ; 0fe50h in Program Space ; definesc punctul de intrare in program ; INTM = 1, dezactivez intreruperile globale ; nu folosesc extensia de semn

;Initializare ADC ;Programez timer GPT1 numarare periodica cu perioada de 0.625ms, atingerea perioadei ;lanseaza ADC ;--------------ldp #0e8h ;registrul de pagina => registrele managerului ;de evenimente ;programez registrul GPTCON, pentru semnificatia bitilor vezi documentatia splk #0000000100000000b,GPTCON ;programez registrul T1PER cu perioada timerului splk #12499,T1PR ;incarc valoarea in timer splk #0,T1CNT ;lansez numaratorul prin programare T1CON splk #1001000001000100b,T1CON ;pentru semnificatie vezi documentatia ;Programez ADC (1) si (2): lansare conversie de catre GPT1, generare intrerupere la terminarea ;conversiei ldp #224 ;DP -> pagina registrilor ADC ;primul registru control ADC ;al doilea registru control ADC

splk #1101101101111110b,ADCTRL1 splk #0000010000000110b,ADCTRL2 ;-----------------;Intreruperile ;-------------ldp #0e8h splk #0,EVIMRA splk #0,EVIMRB splk #0,EVIMRC splk splk clrc ldp #0ffffh, IFR #0030h, IMR INTM

;registrul de pagina => registrele managerului ;de evenimente ;maschez toate intreruperile managerului de ;evenimente EV #0 ;sterg intreruperile in asteptare ;activez intreruperile Level 6 si Level 5<-pt. monitor ; Enable global interrupts ;zona maxima de memorie pana la care stochez datele ADC2 ; inceputul zonei de memorie unde stochez datele ADC1 ; inceputul zonei de memorie unde stochez datele ADC2

;-------------;pregatesc memorarea datelor citite lar ar0,#3a0h lar ar1,#310h lar ar2,#360h program_principal: nop nop nop

111

b program_principal ;Rutina citire analogica ;Datele citite sunt stocate in memorie citire_analogica: ldp #0e0h ; DP -> 0x7000 - 0x707f lacc ADCFIFO1 ; citesc data convertita din FIFO1 mar *,ar1 ; registrul curent ar1 sacl *+ lacc ADCFIFO2 ; citesc data convertita din FIFO2 mar *,ar2 ; registrul curent ar2 sacl *+ cmpr 2 bcnd citire_analogica1,NTC ldp #6 lacl #1 sacl sfarsit_memorare citire_analogica1: ret ;Intreruperea ADC Intr_ADC: ldp #0e0h ; DP -> 0x7000 - 0x707f (Event Manager) lacc SYSIVR ; Acc = Peripheral Vector Address Offset sub #0004h ; 0x004 = ADC int bcnd Intr_ADC1, NEQ ; intreruperea n-a fost ceruta de ADC ldp #6 lacc sfarsit_memorare bcnd Intr_ADC1, NEQ ;s-a terminat memorarea call citire_analogica Intr_ADC1: clrc INTM ret ;intrerupere neasteptata - raman aici Phantom_ISR: b Phantom_ISR .end

;intrerupere neprevazuta

PROGRAMUL 3. Program pentru testarea ntreruperilor.


;Acest program este demonstrativ pentru utilizarea intreruperilor ;Voi folosi un numarator de uz general care sa aiba perioada de 0,1 secunde. ;Daca folosesc un factor de prescalare la numarator de 1/128 atunci numaratorul trebuie sa aiba ;perioada de 15625 considerand frecventa de ceas a CPU egala cu 20MHz. ;Astfel perioada va fi: ; T=128*15625/20 000 000 = 0,1 secunde ;La fiecare zecime de secunda managerul de evenimente va genera o intrerupere pe care o ;folosesc pentru realizarea ceasului ;Pentru activarea intreruperilor trebuie validat: fanionul INTM=0, registrul IFR si ;registrul EVIMRx, x=A, B sau C din managerul de evenimente ;Numaratorul este programat in mod numarare directa continua (SPRU161B.PDF - pag. (2-20) 59) ;In registrul perioadei se inscrie 15624 din cauza ca numarul de impulsuri numarate este ;TxPR+1 impulsuri prescalate (divizate). In GPTCON fanionul directiei trebuie sa fie 1. ;Intrarea TMRDIR este ignorata in acest mod. ;Programul merge bine si masurarea timpului este foarte precisa. .nolist .include "..\\..\\..\\include\\pathway.inc"

;tabela de intreruperi ;Se foloseste timerul de uz general 1 care genereaza o intrerupere in grupul A al managerului

112

;de evenimente care este conectata la INT 2 (Level 2) a CPU. .ps 0fe00h b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b .list ;programul principal ;datele .ds 300h zsecunda .word 0 secunda .word minut ora 0 .word 0 .word 0 .ps 0fe50h .entry start: setc clrc ;initializarea timerului GP 1 ldp #0e8h ;registrul de pagina => registrele managerului ;de evenimente INTM sxm ; INTM = 1, dezactivez intreruperile globale ; nu folosesc extensia de semn ; adresa de inceput a programului ; 0fe50h in Program Space ; definesc punctul de intrare in program 0000h Phantom_ISR Intr_zsecunda Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR ; starting address for this section is ; 0fe00h in Program Space (CNF = 1) ; (00h) Hardware Reset ; (02h) Interrupt Level 1 ; (04h) Interrupt Level 2 - tratez intreruperea la ; o secunda generata de timer GP 1 ; (06h) Interrupt Level 3 ; (08h) Interrupt Level 4 ; (0Ah) Interrupt Level 5 ; (0Ch) Interrupt Level 6 ; (0Eh) Reserved ; (10h) User-defined Software Interrupt ; (12h) User-defined Software Interrupt ; (14h) User-defined Software Interrupt ; (16h) User-defined Software Interrupt ; (18h) User-defined Software Interrupt ; (1Ah) User-defined Software Interrupt ; (1Ch) User-defined Software Interrupt ; (1Eh) User-defined Software Interrupt ; (20h) User-defined Software Interrupt ; (22h) TRAP instruction vector ; (24h) Nonmaskable interrupt (NMI) ; (26h) Reserved ; (28h) User-defined Software Interrupt ; (2Ah) User-defined Software Interrupt ; (2Ch) User-defined Software Interrupt ; (2Eh) User-defined Software Interrupt ; (30h) User-defined Software Interrupt ; (32h) User-defined Software Interrupt ; (34h) User-defined Software Interrupt ; (36h) User-defined Software Interrupt ; (38h) User-defined Software Interrupt ; (3Ah) User-defined Software Interrupt ; (3Ch) User-defined Software Interrupt ; (3Eh) User-defined Software Interrupt

;programez registrul GPTCON, pentru semnificatia bitilor vezi documentatia

113

splk #0000000000111111b,GPTCON ;programez registrul T1PER cu perioada timerului splk #15624,T1PR ;incarc valoarea in timer splk #0,T1CNT ;acum pregatesc intreruperile si lansez numaratorul mai tarziu prin scriere T1CON ;maschez toate intreruperile in afara de intreruperea la perioada a timerului GP 1 din ;registrii de mascare a EV splk #00000000010000000b,EVIMRA splk #0,EVIMRB splk #0,EVIMRC splk #0ffffh,EVIFRA ;sterg eventualele intreruperi in asteptare ;maschez toate intreruperile in afara de Level 2 (timer) si Level 5 (pentru monitor) din IMR ldp #0 splk #0ffffh,IFR splk #0012h,IMR ;sterg eventualele intreruperi in asteptare ;validez intreruperile ;registrul de pagina => registrele managerului ;de evenimente ;pentru semnificatie vezi documentatia ;validez intreruperile globale nop nop nop ldp #6 lacc secunda sub #60 bcnd un_minut,EQ b bucla_principala un_minut: lacc #0 sacl secunda lacc minut add #1 sacl minut sub #60 bcnd o_ora,EQ b bucla_principala o_ora: lacc #0 sacl minut lacc ora add #1 sacl ora sub #24 bcnd o_zi,EQ b bucla_principala lacc #0 sacl ora b bucla_principala

;lansez numaratorul prin programare T1CON ldp #0e8h splk #1001011101000100b,T1CON clrc INTM bucla_principala:

o_zi:

;rutina de intrerupere

114

Intr_zsecunda: ldp #6 lacc zsecunda add #1 sacl zsecunda sub #10 bcnd o_secunda,EQ Intr_zsecunda_iesire: ldp #0e8h ; splk #0ffffh,IFR splk #00080h,EVIFRA clrc INTM ret lacc #0 sacl zsecunda lacc secunda add #1 sacl secunda b Intr_zsecunda_iesire ;intrerupere neasteptata - raman aici Phantom_ISR: b Phantom_ISR .end ;registrul de pagina => registrele managerului ;de evenimente ;sterg eventualele intreruperi in asteptare ;ACHIT INTRERUPEREA ! ;reactivez intreruperile si ma reintorc

o_secunda:

;intrerupere neprevazuta

PROGRAMUL 4. Testare PWM.


;Acest program nu este unul PWM propriu-zis. Se va genera cu ajutorul GP timer 2 un semnal ;cu factor de umplere 50% pentru (simetric) a carui frecventa sa poata fi modificata. ;Pentru aceasta se va programa timerul GP 2 in modul numarare continuu sus/jos. ;Relatia de calcul a duratei active a impulsului este: ; TxPR - TxCMPR ;Daca se ia TxCMPR = TxPR div 2 atunci se obtine un semnal simetric cu perioada TxPR ;Frecventa impulsurilor este data de variatia vitezei de rotatie a motorului care este ;intre 30 rot/min si 3000 rot/min adica 1ntre fmot= 0.5Hz si 50Hz. ;Frecventa de comanda este data de relatia f=6720 * fmot deci f= 3360Hz si 336000Hz. ;Raportul intre frecventa minima si cea maxima este 100. ;Calculez factorul de prescalare. ;Ceasul CPU are 20MHz. Rezulta ca valoarea ce trebuie scrisa in registrul perioadei pentru ;a obtine 3360Hz la iesire este: fCPU/(3360 * 2) = 2977 (aproximativ 3359Hz) ;iar pentru a obtine 336000Hz este: fCPU/(336000 * 2) = 30 (333 333Hz). ;Inmultesc cu 2 din cauza ca o perioada a semnalului generat este de 2 ori mai mare decat ;perioada inscrisa in numarator. Perioada este de fapt 2 x (TxPR+1). ;Cum pot calcula aceste valori, rezulta factor de prescalare = 1 ;Iesirea compare/PWM folosita este cea a timerului GPT2: T2PWM/T2CMP/IOPB4 care se gaseste ;la pinul 13 a conectorului P13 (MC-BUS primary) (Pathway). ;Nu folosesc intreruperile. .nolist .include

"..\\..\\..\\include\\pathway.inc"

;tabela de intreruperi ;nu folosesc deocamdata intreruperile dar tabela trebuie initializata .ps 0fe00h b 0000h ; starting address for this section is ; 0fe00h in Program Space (CNF = 1) ; (00h) Hardware Reset

115

b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b .list ;programul principal ;definesc variabile inmultire .ds 300h ct_f_min ct_f_max

Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR

; (02h) Interrupt Level 1 ; (04h) Interrupt Level 2 ; (06h) Interrupt Level 3 ; (08h) Interrupt Level 4 ; (0Ah) Interrupt Level 5 ; (0Ch) Interrupt Level 6 ; (0Eh) Reserved ; (10h) User-defined Software Interrupt ; (12h) User-defined Software Interrupt ; (14h) User-defined Software Interrupt ; (16h) User-defined Software Interrupt ; (18h) User-defined Software Interrupt ; (1Ah) User-defined Software Interrupt ; (1Ch) User-defined Software Interrupt ; (1Eh) User-defined Software Interrupt ; (20h) User-defined Software Interrupt ; (22h) TRAP instruction vector ; (24h) Nonmaskable interrupt (NMI) ; (26h) Reserved ; (28h) User-defined Software Interrupt ; (2Ah) User-defined Software Interrupt ; (2Ch) User-defined Software Interrupt ; (2Eh) User-defined Software Interrupt ; (30h) User-defined Software Interrupt ; (32h) User-defined Software Interrupt ; (34h) User-defined Software Interrupt ; (36h) User-defined Software Interrupt ; (38h) User-defined Software Interrupt ; (3Ah) User-defined Software Interrupt ; (3Ch) User-defined Software Interrupt ; (3Eh) User-defined Software Interrupt

.word 2977 ;constanta pentru frecventa minima la iesire .word 30 ;constanta pentru frecventa maxima la iesire .ps 0fe50h .entry

;initializari ;sterg extensia de semn clrc sxm ;validarea iesirii comparare/PWM a timerului GPT2 ;Pentru aceasta trebuie scris 1 in OCRA[12] ldp splk #0e1h #1000h, OCRA ; DP -> 0x7090 - 0x70ff ; activarea pinului se face in registrul OCRA ;nu folosesc extensia de semn

;programarea numaratorului GPT2 ldp #232 splk #0000000001001000b, GPTCON ldp #6 lacl ct_f_max ;incarc acumulatorul cu ct. de frecventa ldp #232 ; DP -> 0x7400 - 0x747f (Event Manager) sacl T2PR ;programez perioada sfr ;acumulator = acumulator div 2 (pt. comparare) sacl T2CMP

116

;programez GPT2 si lansez numaratoarea splk #1010100001000010b, T2CON start: nop nop nop b start Phantom_ISR: b Phantom_ISR .end ;aici nu fac nimic deocamdata...

PROGRAM 5. Program pentru testarea QEP - unitii de citire a impulsurilor codate n cuadratur.
;Acest program este demonstrativ pentru utilizarea QEP ;Conectez la intrarea QEP un TIRO ;Citesc QEP in registrul GPTimer 3. Continutul registrului imi da pozitia iar sensul de numarare ;imi da sensul de rotatie ;Testez acum citirea in intreruperi. Intreruperea este data de RTI la 15.63ms ;(RTIPS2..RTIPS0 = 100) ;Memorez datele in zona de memorie de la 310h pe 64 octeti ca sa vad variatia vitezei ;Rezultatul masuratorii se imparte la patru pentru a obtine numarul real de impulsuri pe durata ;de 15.63 ms .nolist .include ;tabela de intreruperi .ps 0fe00h b b b b b b b b b b b b b b b b b b b b b b b b b b 0000h Intr_monitor Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR ; starting address for this section is ; 0fe00h in Program Space (CNF = 1) ; (00h) Hardware Reset ; (02h) Interrupt Level 1 (intrerupere la 15.63ms) ; (04h) Interrupt Level 2 ; (06h) Interrupt Level 3 ; (08h) Interrupt Level 4 ; (0Ah) Interrupt Level 5 ; (0Ch) Interrupt Level 6 ; (0Eh) Reserved ; (10h) User-defined Software Interrupt ; (12h) User-defined Software Interrupt ; (14h) User-defined Software Interrupt ; (16h) User-defined Software Interrupt ; (18h) User-defined Software Interrupt ; (1Ah) User-defined Software Interrupt ; (1Ch) User-defined Software Interrupt ; (1Eh) User-defined Software Interrupt ; (20h) User-defined Software Interrupt ; (22h) TRAP instruction vector ; (24h) Nonmaskable interrupt (NMI) ; (26h) Reserved ; (28h) User-defined Software Interrupt ; (2Ah) User-defined Software Interrupt ; (2Ch) User-defined Software Interrupt ; (2Eh) User-defined Software Interrupt ; (30h) User-defined Software Interrupt ; (32h) User-defined Software Interrupt "..\\..\\..\\include\\pathway.inc"

117

b b b b b b .list ;programul principal ;datele

Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR

; (34h) User-defined Software Interrupt ; (36h) User-defined Software Interrupt ; (38h) User-defined Software Interrupt ; (3Ah) User-defined Software Interrupt ; (3Ch) User-defined Software Interrupt ; (3Eh) User-defined Software Interrupt

.ds 300h numar_impuls_QEP .word 0 sens .word 0 contor_intrerupere .word 1 ;aici trebuie initializat cu 1 ca sa sar prima intrerupere sfarsit_memorare .word 0 ;cand nu mai memorez datele pun 1 ;program .ps 0fe50h .entry start: setc clrc setc INTM sxm xf ; INTM = 1, dezactivez intreruperile globale ; nu folosesc extensia de semn ;aprind LED xf (daca e stins) ; adresa de inceput a programului ; 0fe50h in Program Space ; definesc punctul de intrare in program

;prima data trebuie sa comut pinii care sunt utilizati in comun de functia primara (aici ;CAPx/QEPx) si pinii porturilor I/O ldp #0e1h ; DP -> 0x7090 - 0x70ff

; activez pinii QEP1 (bit 4 = 1) si QEP2 (bit 5 = 1) splk #0030h, OCRB ; activarea pinilor se face in registrul OCRB ; initializez CAPFIFO stivele unitatii de captura (sterg toti bitii) ldp #0e8h ; DP -> 0x7400 - 0x747f (Event Manager) splk #00ffh, CAPFIFO ; setez registrul de control al GPTimer splk #0,GPTCON ; configurare GPTimer3 splk #0FFFFh, T3PR ; setez perioada GPTimer3 splk #00000h, T3CNT ; set contor GPTimer3 splk #1101100001110000b,T3CON ;registrul de control GPTimer3 ; initializare CAPCON splk #0110000000000000b, CAPCON splk #1110000000000000b, CAPCON ;initializarea timerului de timp real IRT ldp #0e0h splk #01000100b,RTICR ;registrul de pagina => registrele sistem ;intrerupere la 15.63 ms, validez intreruperile

;maschez toate intreruperile in afara de Level 1 (IRT) si Level 5 (pentru monitor) din IMR ldp #0 splk #0ffffh,IFR splk #0011h,IMR clrc INTM lar ar0,#350h ;pagina zero de memorie ;sterg eventualele intreruperi in asteptare ;validez intreruperile ; activare intreruperi ; sfarsitul zonei de memorie unde stochez datele

118

lar ar1,#310h mar *,ar1 Program_principal: nop nop b Program_principal

; inceputul zonei de memorie unde stochez datele ; registrul ar1 este registrul curent

;Rutina de citire a contorului QEP (impulsuri codate in cuadratura - TIRO) Citire_QEP: ldp #0e8h ; DP -> 0x7400 - 0x747f (Event Manager) lacl T3CNT ; citesc continutul numaratorului T3CNT ldp #6 sacl numar_impuls_QEP ;memorez numar impulsuri ldp #0e8h ; DP -> 0x7400 - 0x747f (Event Manager) bit GPTCON, 0 ; verific stare GPT3: numara sus sau jos bcnd Numara_sus,TC ;valoarea bitului testat este copiata in bit TC Numara_jos: ldp #6 lacl #0 sacl sens lacl numar_impuls_QEP neg sacl numar_impuls_QEP b Iesire_QEP Numara_sus: ldp #6 lacl #1 sacl sens Iesire_QEP: ldp #0e8h ; DP -> 0x7400 - 0x747f (Event Manager) splk #00000h, T3CNT ; sterg contor GPTimer3 ret ;Rutina de memorare valori citite de la QEP pentru a vedea corectitudinea Memorare_date: ldp #6 lacl numar_impuls_QEP sacl *+ cmpr 2 bcnd cont_mem,NTC lacl sfarsit_memorare add #1 sacl sfarsit_memorare cont_mem: ret ;Intrerupere IRT Intr_monitor: ldp #6 lacc contor_intrerupere sub #1 bcnd Intr_monitor1,EQ call Citire_QEP ldp #6 lacc sfarsit_memorare cc Memorare_date,EQ clrc INTM ret Intr_monitor1: lacc #5 sacl contor_intrerupere clrc INTM ret ;o valoare oarecare diferita de 1

;nu ma intereseaza prima intrerupere

;cat timp sfarsit_memorare=0 pot memora

119

;intrerupere neasteptata - raman aici Phantom_ISR: b Phantom_ISR .end

;intrerupere neprevazuta

PROGRAM 6. Salvarea i restaurarea regitrilor de stare ai CPU.


;Testez salvarea si restaurarea registrilor de stare ai CPU .nolist .include "..\\..\\..\\include\\pathway.inc"

;tabela de intreruperi ;nu folosesc deocamdata intreruperile dar tabela trebuie initializata .ps 0fe00h b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b .list ;programul principal ;definesc variabile inmultire .ds 300h RStare0 .word 0 ;Stochez registrul de stare 0 RStare1 .word 0 ;Stochez registrul de stare 1 .ps 0fe50h .entry 0000h Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR Phantom_ISR ; starting address for this section is ; 0fe00h in Program Space (CNF = 1) ; (00h) Hardware Reset ; (02h) Interrupt Level 1 ; (04h) Interrupt Level 2 ; (06h) Interrupt Level 3 ; (08h) Interrupt Level 4 ; (0Ah) Interrupt Level 5 ; (0Ch) Interrupt Level 6 ; (0Eh) Reserved ; (10h) User-defined Software Interrupt ; (12h) User-defined Software Interrupt ; (14h) User-defined Software Interrupt ; (16h) User-defined Software Interrupt ; (18h) User-defined Software Interrupt ; (1Ah) User-defined Software Interrupt ; (1Ch) User-defined Software Interrupt ; (1Eh) User-defined Software Interrupt ; (20h) User-defined Software Interrupt ; (22h) TRAP instruction vector ; (24h) Nonmaskable interrupt (NMI) ; (26h) Reserved ; (28h) User-defined Software Interrupt ; (2Ah) User-defined Software Interrupt ; (2Ch) User-defined Software Interrupt ; (2Eh) User-defined Software Interrupt ; (30h) User-defined Software Interrupt ; (32h) User-defined Software Interrupt ; (34h) User-defined Software Interrupt ; (36h) User-defined Software Interrupt ; (38h) User-defined Software Interrupt ; (3Ah) User-defined Software Interrupt ; (3Ch) User-defined Software Interrupt ; (3Eh) User-defined Software Interrupt

120

;initializari ldp #06h setc sxm start: clrc INTM ;activez intreruperile lar ar0,#0300h ;acestea sunt registrele pe care le folosesc in program lar ar1,#0350h ; -''mar *,ar0 ;registrul implicit este ar0 lar ar6,#RStare0 ;registrul folosit pentru salvarea registrilor de stare ldp #0e0h ;registrul de pagina mar *,ar6 ;pregatesc salvarea registrilor de stare setc INTM ;dezactivez intreruperile sst #0,*+ ;salvez ST0 sst #1,*;salvez ST1 setc INTM ldp #6 ;schimb registrul de pagina sa vad daca va fi restaurat lst #0,*+ ;restaurez ST1 lst #1,*;restaurez ST0 ;aici ar trebui sa fie din nou ar0 registru implicit si DP la 0e0h ;OK asa se si intampla... b start Phantom_ISR: b Phantom_ISR .end ;registrul de pagina din Memoria Date ;folosesc extensia de semn

121

CAPITOLUL 4
PROGRAMAREA MICROCONTROLERELOR DE TIP PIC12, PIC16 I PIC 18
Unitile centrale de tip de tip RISC PIC12, PIC16 i PIC18 au un set de 35 de instruciuni cu lungimea de 14 bii. Programarea acestora se face cu ajutorul mediului de programare MPLAB furnizat gratuit de firma Microchip. Programul obinut n cod obiect absolut este n format Intel Hex specific programatoarelor cu ajutorul crora programul este nscris n memoria microcontrolerului. Programarea microcontrolerelor PIC poate fi fcut prin intermediul interfeei ICSP (In-Circuit Serial Programming). Aceast interfa conine 5 linii dintre care pe dou linii se transmit datele n format serial i semnalul de ceas a acestora iar pe celelalte trei sunt aplicate tensiunea de alimentare, tensiunea de programare i masa (potenialul de referin). Toate aceste linii sunt comune cu liniile microcontrolerului pe care sunt n mod obinuit semnale ale perifericelor. Programarea unui microcontroler presupune mai nti scrierea programului surs ntr-un limbaj de nivel nalt (Pascal, Basic, C etc) sau in limbaj de asamblare, compilarea acestuia i scrierea programului n memoria Flash a microcontrolerului. Toate programatoarele destinate microcontrolerelor necesit ca programele direct executabile, care vor fi nscrise n memoria de program a microcontrolerului, s fie sub un format special denumit format hexazecimal. Aceast denumire provine din faptul c aceste fiiere conin codul program sub form hexazecimal, scris cu caractere ASCII.

4.1.

Organizarea memoriei microcontrolerelor PIC

Datorit faptului c microcontrolerele din familiile PIC12, PIC16 i PIC18 au aceeai structur a unitii centrale, diferenele aprnd datorit perifericelor existente i a memoriei folosite, vom prezenta n continuare structura unui microcontroler simplu, utilizat pe scar larg, microcontrolerul PIC16F84A. Memoria microcontrolerului se compune din: memorie flash - unde se scrie programul; eeprom - memorie de date - date importante pentru program; ram - date temporare in execuia programului. Registre: 122

registrul de lucru w; registrul de stare (status) - conine biii de stare; GPR (General Purpose Registers) - registre de uz general; SFR SpecialFunction Registers - registre cu funcie special; Stiva este separat i are opt nivele. PIC16F84 are dou blocuri separate de memorie, unul pentru date i cellalt pentru programe. Memoria EEPROM i registrele GPR n memoria RAM constituie blocul de date iar memoria FLASH constituie un blocul de programe.

123

4.1.1. Memoria program Memoria de program este o memorie flash. Mrimea memoriei program este de 1024 locaii cu lime de 14 bii unde locaiile zero i patru sunt rezervate pentru reset i pentru vectorul ntrerupere. 4.1.2. Memoria de date Memoria de date const din memoriile EEPROM i RAM. Memoria EEPROM const din 64 de locaii de opt bii a cror coninut nu este pierdut n timpul opririi sursei de alimentare. EEPROM-ul nu este direct adresabil, dar este accesat indirect prin regitrii EEADR i EEDATA. Pentru c memoria EEPROM este folosit curent la memorarea unor parametri importani (de exemplu, o temperatur dat n regulatoarele de temperatur), exist o procedur strict de scriere n EEPROM ce trebuie urmat pentru a preveni scrierea accidental. Memoria RAM pentru date ocup un spaiu ntr-o hart a memoriei de la locaia 0x0C la 0x4F ceea ce nseamn 68 de locaii. Locaiile memoriei RAM sunt de asemenea denumite registre GPR care este o abreviere General Purpose Registers-Registre cu Scop General. Registrele GPR pot fi accesate indiferent de ce banc este selectat la un moment. 4.1.3. Registrele SFR La microcontrolerul 16F64A registrele ce ocup primele 12 locaii n bancurile 0 i 1 sunt registre cu funcii speciale asociate cu unele blocuri ale microcontrolerului. Acestea sunt numite Special Function Registers - Registre cu Funcii Speciale. 4.1.4. Bancuri de Memorie n afar de aceast diviziune n 'lungime' a registrelor SFR i GPR, harta memoriei este de asemenea mprit n 'adncime' n zone numite 'bancuri'. Selectarea unuia din bancuri se face de biii RPO i RP1 din registrul STATUS de stare. Exemplu:
bcf STATUS, RP0

Instruciunea BCF terge bitul RP0 (RP0=0) n registrul STATUS i astfel seteaz bancul 0.
bsf STATUS, RP0

Instruciunea BSF seteaz bitul RP0 (RP0=1) n registrul STATUS i astfel seteaz bancul 1. Cu ajutorul macrocomenzilor, selecia dintre dou bancuri devine mai clar i programul mult mai inteligibil.
BANK0 macro Bcf STATUS, RP0 ;Select memory bank 0

124

Endm BANK1 macro Bsf STATUS, RP0 Endm

;Select memory bank 1

NOT: Locaiile 0Ch - 4Fh sunt registre cu scop general (GPR) ce sunt folosii ca memorie RAM. Cnd sunt accesate locaiile 8Ch - CFh n Bancul 1, accesm de fapt exact aceleai locaii n Bancul 0. Cu alte cuvinte, cnd trebuie accesat unul din registrele GPR, nu trebuie inut cont de banc. 4.1.5. Contorul de Program Contorul de program (PC) este un registru de 13 bii ce conine adresa instruciunii ce se execut. Prin incrementarea sau schimbarea sa (ex. n caz de salturi) microcontrolerul execut instruciunile de program pas-cu-pas. 4.1.6. Stiva PIC16F84 are o stiv de 13 bii cu 8 nivele, sau cu alte cuvinte, un grup de 8 locaii de memorie, de 13 bii lime, cu funcii speciale. Rolul su de baz este de a pstra valoarea contorului de program dup un salt din programul principal la o adres a unui subprogram. Pentru ca un program s tie cum s se ntoarc la punctul de unde a s-a produs un salt la un subprogram, trebuie s salveze valoarea contorului programului n stiv. Cnd se produce saltul dintr-un program ntr-un subprogram, contorul programului este salvat n stiv (de exemplu la execuia instruciunii CALL). Cnd se execut o instruciune ca RETURN, RETLW sau RETFIE ce se gsete la sfritul unui subprogram, contorul programului este extras din stiv, n aa fel nct programul principal s poat continua execuia din punctul n care a fost ntrerupt la apariia apelului de subprogram. Aceste operaii de plasare ntr-o i luare dintr-o stiv a contorului de program sunt numite PUSH i POP, la fel cu instruciunile similare ale unor microcontrolere mai mari. 4.1.7. Registrul STATUS (ADRESA: 03h, 83h) Registrul STATUS conine starea aritmetic ALU (C, DC, Z), starea RESET (TO, PD) i biii pentru selectarea bancului de memorie (IRP, RP1, RP0). Considernd c selecia bancului de memorie este controlat prin acest registru, el trebuie s fie prezent n fiecare banc. Registrul STATUS poate fi o destinaie pentru orice instruciune, cu oricare alt registru. Dac registrul STATUS este o destinaie pentru instruciunile ce afecteaz biii Z, DC or C, atunci scrierea n aceti trei bii nu este posibil. R/W-0 R/W-0 R/W-0 R - 1 R - 1 R/W-x R/W-x R/W-x IRP RP1 RP0 /TO /PD Z DC C Bit 7 bit 6 bit 5 bit 4 Bit 3 bit 2 bit 1 bit 0 R = bit de citire; W = bit de scriere U = bit neimplementat, citit ca zero; n = valoare la resetul power-on; '1' = bitul este setat; '0' = bitul este resetat; x = valoarea bitului este nu este cunoscut 125

Bit 0 C (Carry bit) - Transfer. Bit care este afectat de operaiile de adunare, scdere i transfer. 1 = s-a produs un transfer din bitul cel mai semnificativ al rezultatului; 0 = transferul nu s-a produs. Bitul C este afectat de instruciunile: addwf, addlw, sublw, subwf. Bit 1 DC (Digit Carry bit) - DC transfer. Bit afectat de operaiile de adunare, scdere i transfer. Spre deosebire de bitul C, acest bit reprezint transferul ntre biii mediani ai rezultatului. Este setat la adunare cnd se produce un transport de la bitul 3 la bitul 4, sau de scdere cnd se produce mprumutul de la bitul 4 de ctre bitul 3, sau transfer n ambele direcii. 1 = transfer produs la al patrulea bit al rezultatului; 0 = transferul nu s-a produs. Bitul DC este afectat de instruciunile: addwf, addlw, sublw, subwf. Bit 2 Z (Zero bit) - indic un rezultat egal cu zero. Acest bit este setat atunci cnd rezultatul unei operaii logice sau aritmetice executate este zero. 1 = rezultatul este egal cu zero; 0 = rezultat diferit de zero. Bit 3 /PD (Power Down bit) Bit ce este setat cnd microcontrolerul este alimentat i ncepe s funcioneze, dup fiecare reset obinuit i dup executarea instruciunii CLRWDT. Instruciunea SLEEP reseteaz acest bit cnd microcontrolerul intr n regimul de consum redus. Setarea lui repetat este posibil prin reset sau prin oprirea i pornirea sursei. Setarea poate fi triggerat de asemenea de un semnal de la pinul RB0/INT, de o schimbare la portul RB, la terminarea scrierii n EEPROM-ul de date intern i de watchdog. 1 = dup ce sursa a fost pornit; 0 = executarea instruciunii SLEEP. Bit 4 /TO (Time Out bit) - depirea (overflow) a watchdog-ului Bitul este setat dup pornirea sursei de alimentare i execuia instruciunilor: CLRWDT i SLEEP. Bitul este resetat cnd watchdog-ul ajunge la sfrit semnalnd c ceva nu este n ordine. 1= depirea-oveflow nu s-a produs; 0= depirea-overflow s-a produs. Bit 6:5 RP1:RP0 (Register Bank Select bits) - bii de selectare a bancului de registre Aceti doi bii reprezint partea superioar a adresei la adresarea direct. Pentru c instruciunile ce adreseaz memoria direct au doar apte bii de adres mai este necesar de nc un bit pentru a adresa cei 256 octei ci are PIC16F84. Bitul RP1 nu este folosit, dar este lsat pentru extinderi viitoare ale acestui microcntroler. 01= primul banc 00= bancul zero 126

Bit 7 IRP (Register Bank Select bit) - bit de selectare a bancului de regitri. Bit al crui rol este de a fi al optulea bit la adresarea indirect a RAM-ului intern. 1= bancul 2 i 3 0= bancul 0 i 1 (de la 00h la FFh) 4.1.8. Registrul OPTION (ADRESA: 81h) Registrul OPTION este un registru n care se poate scrie i care se poate citi i care conine diferii bii de configurare pentru circuitul de prescalare TMR0/WDT, ntreruperea extern INT, TMR0 i the weak pull-ups on PORTB. R/W-1 /RBPU bit 7 R/W-1 INTEDG bit 6 R/W-1 TOCS bit 5 R/W-1 TOSE bit 4 R/W-1 PSA bit 3 R/W-1 PS2 bit 2 R/W-1 PS1 bit 1 R/W-1 PS0 bit 0

R = bit de citire; W = bit de scriere U = bit neimplementat, citit ca zero; n = valoare la resetul power-on; '1' = bitul este setat; '0' = bitul este resetat; x = valoarea bitului este nu este cunoscut Bit 0:2 PS0, PS1, PS2 (Prescaler Rate Select bits) - Bit Selecie Rat Prescaler Aceti trei bii definesc valoarea constantei de prescalare a contorului de temporizare (timer) TMR0. Biii 000 001 010 011 100 101 110 111 TMR0 1:2 1:4 1:8 1:16 1:32 1:64 1:128 1:256 WDT 1:1 1:2 1:4 1:8 1:16 1:32 1:64 1:128 Asignare Prescaler.

Bit 3 PSA (Prescaler Assignment bit) - Bit de Bit ce asigneaz prescalerul ntre TMR0 i watchdog. 1= prescalerul este asignat watchdog-ului 0= prescalerul este asignat timer-ului liber (free-run) TMR0.

Bit 4 T0SE (TMR0 Source Edge Select bit) - Bit Selecie a Frontului Sursei TMR0. Dac este permis de a se triggera TMR0 prin impulsurile de la pinul RA4/T0CKI, acest bit determin dac aceasta va fi la frontul descresctor sau cresctor al unui semnal. 1= front cresctor 0= front descresctor Bit 5 TOCS (TMR0 Clock Source Select bit) - Bit Selecie Surs Ceas TMR0. Acest pin permite timerului liber (free-run) s incrementeze starea lui fie de la 127

oscilatorul intern la fiecare a ceasului oscilatorului, fie prin impulsuri externe la pinul RA4/T0CKI. 1= impulsuri externe 0= ceas intern 1/4 Bit 6 INTEDG (Interrupt Edge Select bit) - Bit de Selecie a Frontului ntrerupere. Dac ntreruperea este activat este posibil ca acest bit s determine frontul la care o ntrerupere va fi activat la pinul RB0/INT. 1= front cresctor 0= front descresctor Bit 7 /RBPU (PORTB Pull-up Enable bit) - Bit Enable-Activare Pull-up PORTB. Acest bit activeaz sau dezactiveaz rezistoarele interne 'pull-up'- de ieire la portul B. 1= Rezistori oprire "pull-up" 0= Rezistori pornire "pull-up" 4.1.9. Registrul INTCON (ADRESA: 0Bh, 8Bh) Registrul INTCON este un registru ce poate fi scris i citit i care conine diferii bii de validare pentru toate sursele de ntrerupere. R/W-0 GIE bit 7 R/W-0 EEIE Bit 6 R/W-0 T0IE bit 5 R/W-0 INTE bit 4 R/W-0 RBIE bit 3 R/W-0 T0IF bit 2 R/W-0 INTF bit 1 R/W-x RBIF bit 0

R = bit de citire; W = bit de scriere U = bit neimplementat, citit ca zero; n = valoare la resetul power-on; '1' = bitul este setat; '0' = bitul este resetat; x = valoarea bitului este nu este cunoscut Bit 7 GIE (Global Interrupt Enable bit) - bit de validare global a ntreruperilor. 1 = valideaz toate ntreruperile nemascate 0 = dezactiveaz toate ntreruperile Bit 6 EEIE (EE Write Complete Interrupt Enable bit) - bit de validare a ntreruperii de scriere a memoriei EEPROM 1 = activeaz EE Write Complete Interrupts 0 = dezactiveaz EE Write Complete Interrupts Bit 5 T0IE (TMR0 Owerflow Interrupt Enable bit) - bit de validare a ntreruperii de depire al temporizatorului TMR0 1 = valideaz ntreruperile TMR0 0 = dezactiveaz ntreruperile TMR0 Bit 4 INTE (RB0/INT External Interrupt Enable bit) - bit de validare a ntreruperii externe 1 = valideaz ntreruperea extern RB0/INT 0 = dezactiveaz ntreruperea extern RB0/INT 128

Bit 3 RBIE (RB Port Change Interrupt Enable bit) - bit de validare a ntreruperii la schimbare produs la port RB 1 = valideaz ntreruperea 0 = invalideaz ntreruperea Bit 2 T0IF (TMR0 Overflow Interrupt Flag bit) - fanionul de semnalizare a ntreruperii de depire a TMR0 1 = registrul TMR0 a fost depit (fanionul trebuie ters prin software) 0 = registrul TMR0 nu a fost depit Bit 1 INTF (RB0/INT External Interrupt Flag bit) - fanion de semnalizare a ntreruperii externe 1 = ntreruperea extern RB0/INT s-a produs (fanionul trebuie ters prin program) 0 = ntreruperea extern RB0/INT nu s-a produs bit 0 RBIF (RB Port Change Interrupt Flag bit) - fanion de semnalizare a ntreruperii de apariie a unei schimbri la portul RB 1 = la cel puin unul din pinii RB7 - RB4 a aprut o schimbare de stare (trebuie ters prin program) 0 = la nici unul din pinii RB7 - RB4 nu a aprut o schimbare de stare 4.1.10. PCL i PCLATH Contorul de program (PC) indic adresa instruciunii ce urmeaz a fi executat. PC are o lime de 13 bii. Cel mai puin semnificativ octet este registrul PCL. Acest registru poate fi scris i citit. Cel mai semnificativ octet este registrul PCH. Acest registru conine biii PC<12:8> i nu poate fi scris i citit direct. Dac valoarea contorului de program (PC) este modificat sau un test de condiie este adevrat, instruciunea necesit dou cicluri. Al doilea ciclu este executat ca o instruciune NOP. Toate actualizrile registrului PCH se fac prin intermediul registrului PCLATH. 4.1.11. Memoria de date EEPROM Memoria de date se adreseaz n mod indirect prin intermediul registrelor cu funcii speciale. Sunt patru registre SFR pentru scrierea i citirea memoriei EEPROM: EECON1, EECON2 (registru neimplementat fizic), EEDATA i EEADR. EEDATA conine cei opt bii de date pentru scriere sau citire iar EEADR conine adresa locaiei de memorie EEPROM ce va fi accesata. PIC16F84A are 64 de octei de memorie EEPROM adresabili n plaja 0h la 3Fh. Memoria de date EEPROM permite att scrierea ct i citirea. Un octet scris terge n mod automat locaia nainte de a scrie data (erase before write). 4.1.12. Registrul EECON1 (ADRESA: 88h) U-0 bit 7 U-0 Bit 6 U-0 bit 5 R/W-0 EEIF bit 4 R/W-x WRERR bit 3 129 R/W-0 WREN bit 2 R/S-0 WR bit 1 R/S-0 RD bit 0

R = bit de citire; W = bit de scriere U = bit neimplementat, citit ca zero; n = valoare la resetul power-on; '1' = bitul este setat; '0' = bitul este resetat; x = valoarea bitului este nu este cunoscut Biii 7-5 Neimplementai - sunt citii ca '0' Bit 4 EEIF (EEPROM Write Operation Interrupt Flag bit) - fanion de semnalizare a ntreruperii de scriere a EEPROM 1 = operaia de scriere terminat (bitul trebuie ters prin program) 0 = operaia de scriere nu s-a terminat sau nu a nceput Bit 3 WRERR (EEPROM Error Flag bit) - fanion de eroare a operaiei de scriere n EEPROM 1 = operaia de scriere s-a terminat prematur (orice reset /MCLR sau orice reset WDT pe durate operrii normale) 0 = operaia de scriere s-a terminat Bit 2 WREN (EEPROM Write Enable bit) - bit de validare a scrierii n EEPROM 1 = permite cicluri de scriere 0 = inhib scrierea n memoria EEPROM Bit 1 WR (Write Control bit) - bit de control a scrierii 1 = iniiaz un ciclu de scriere. Bitul este ters de hardware o dat ce scrierea este complet. Bitul WR poate fi numai setat (nu i ters - resetat) prin program. Bit 0 RD (Read Control bit) - bit de control a citirii 1 = iniiaz o citire din EEPROM i este ters de hardware. Bitul RD poate fi numai setat (nu i ters - resetat) prin program. 0 = nu se iniiaz o citire din EEPROM 4.1.13. Citirea memoriei EEPROM Pentru a citi o dat din memoria EEPROM utilizatorul trebuie s scrie adresa n registrul EEADR i s seteze bitul de control RD (EECON1<0>). Data este disponibil n urmtorul ciclu, si deci va putea fi citit de urmtoarea instruciune, n registrul EEDATA care reine aceast dat pn la urmtoarea citire sau scriere din/n memoria EEPROM. Exemplu, citire din memoria EEPROM:
BCF STATUS, RP0 MOVLW CONFIG_ADDR MOVWF EEADR BSF STATUS, RP0 BSF EECON1, RD BCF STATUS, RP0 MOCVF EEDATA, W ;Bank 0 ;Address to read ;Bank 1 ;EE Read ;Bank 0 ;W = EEDATA

130

4.1.14. Scrierea n memoria de date EEPROM Pentru a scrie ntr-o locaie a memoriei EEPROM utilizatorul trebuie s scrie adresa locaiei de memorie n registrul EEADR i data n registrul EEDATA. Dup aceasta, utilizatorul trebuie s urmreasc secvena specific pentru a iniia ciclul de scriere. Exemplu, scrierea n memoria EEPROM:
BSF STATUS, RP0 ;Bank 1 BCF INTCON, GIE ;Disable INTs. BSF EECON1, WREN ;Enable Write MOVLW 55h ; ..................................................... MOVWF EECON2 ;Write 55h MOVLW AAh ; MOVWF EECON2 ;Write AAh BSF EECON1, WR ;Set WR bit begin write BSF INTCON, GIE ;Enable INTs. ....................................................

Secvena obligatorie

Scrierea nu este iniiat dac secvena de mai sus nu este realizat exact (se scrie 55h n EECON2, se scrie Aah n EECON2 i apoi se seteaz bitul WR) pentru fiecare octet scris. Este recomandat ca ntreruperile s fie dezactivate pe parcursul acestei secvene de cod. n plus, bitul WREN din registrul EECON1 trebuie setat pentru a permite scrierea. Acest mecanism previne scrierea accidental n memoria de date EEPROM ce poate aprea datorit execuiei neateptate a unei secvene de program (de exemplu programe pierdute). Utilizatorul trebuie s in permanent bitul WREN ters cu excepia cazurilor cnd se face nnoirea coninutului memoriei EEPROM. Bitul WREN nu este ters de ctre hardware. Dup ce secvena de scriere a fost iniiat, tergerea bitului WREN nu va afecta ciclul de scriere. La completarea ciclului de scriere bitul WR este ters de ctre hardware i fanionul de scriere complet n EE (EEIF) este setat. Utilizatorul poate activa ntreruperile sau poate testa prin program acest bit. Bitul EEIF trebuie ters prin program. 4.1.15. Verificarea scrierii n funcie de aplicaie, un obicei bun n programare poate s cear verificarea datelor scrise in memoria EEPROM. Metoda de verificare prezentat n exemplul de mai jos trebuie folosit atunci cnd memoria EEPROM este folosit la limitele de stres. Altfel, euarea scrierii n memoria EEPROM va fi dat de bitul WRERR din registrul EECON1 care ntoarce valoarea unu n caz de eroare. Exemplu de verificare a scrierii n memoria EEPROM:
BCF ; MOVF BSF STATUS, RP0 ;Bank 0 ;Any code can go here EEDATA,W ;Must be in Bank 0 STATUS, RP0 ;Bank 1

READ

131

BSF BCF and read

EECON1, RD ;ZES Read the value written STATUS, RP0 ;Bank 0 ; ;Is the value written (in W reg) ;(in EEDATA) the same? ; ;Is difference 0? ;NO, Write error

SUBWF EEDATE,W BTFSS STATUS, Z GOTO WRITE_ERR

4.1.16. Harta memoriei RAM Adresa registrului Location Location (File Address) 00h INDF INDF Indirect addr.(1) Indirect addr.(1) 01h TMR0 OPTION_REG 02h PCL PCL 03h STATUS STATUS 04h FSR FSR 05h PORTA TRISA 06h PORTB TRISB 07h 08h EEDATA EECON1 09h EEADR EECON2(1) 0Ah PCLATH PCLATH 0Bh INTCON INTCON 0Ch 68 ACEIAI 4Fh REGISTRE DE UZ REGITRII CU GENERAL CEI DIN BANKUL 0 50h LIBER LIBER 7Fh Bank 0 Bank 1 (1) NU REPREZINT UN REGISTRU FIZIC. Prezentarea sumar a registrelor Adresa registrului (File Address) 80h 81h 82h 82h 84h 85h 86h 87h 88h 89h 8Ah 8Bh 8Ch CFh D0h FFh

132

Legend: x = unknown, u = unchanged. - = unimplemented, read as '0', q = value depends on condition Not: 1. Cel mai semnificativ octet al contorului de program nu este direct accesibil. PCLATH este un registru slave pentru PC<12:8>. Coninutul registruluin PCLATH poate fi transferat n octetul cel mai semnificativ al contorului de program dar coninutul PC<12:8> nu poate fi transferat n PCLATH. 2. Biii de stare TO i PD din registrul STATUS nu sunt afectati de /MCLR Reset. 3. Alte iniializri RESET (care nu sunt determinate de cuplarea sursei de alimentare) include RESET extern prin intermediul /MCLR i Watchdog Timer Reset. 4. La orice RESET al dispozitivului, aceti pini sunt sunt configurai ca intrri. 5. Aceasta este valoarea ce va fi n latch-ul portului de ieire. 4.1.17. Moduri de adresare Locaiile de memorie RAM pot fi accesate direct sau indirect.

133

Adresarea Direct

Adresarea Direct Adresarea Direct se face printr-o adres de 9 bii. Aceast adres este obinut prin adugarea la cei apte bii ai adresei directe a unei instruciuni a doi bii (RP1, RP0) din registrul STATUS dup cum se arat n figura urmtoare. Orice acces la registrele SFR poate fi un exemplu de adresare direct.
Bsf STATUS, RP0 ;Bankl movlw 0xFF ;w=0xFF movwf TRISA ;address of TRISA register is taken from ;instruction movwf

Adresarea Indirect Adresarea indirect spre deosebire de cea direct nu ia o adres dintr-o instruciune ci o creeaz cu ajutorul bitului IRP din registrul STATUS i a registrului FSR. Locaia adresat este accesat prin registrul INDF care de fapt conine o adres indicat de FSR. Cu alte cuvinte, orice instruciune care folosete INDF ca registrul al ei, n realitate acceseaz datele indicate de registrul FSR. S spunem, de exemplu, c un registru cu scop general (GPR) la adresa 0Fh conine o valoarea 20. Prin scrierea unei valori 0Fh n registrul FSR vom obine un registru indicator la adresa 0Fh, iar prin citirea din registrul INDF, vom obine valoarea 20, ceea ce nseamn c am citit din primul registru valoarea lui fr accesarea lui direct (dar prin FSR i INDF). Se pare c acest tip de adresare nu are nici un avantaj fa de adresarea direct, dar exist unele nevoi n timpul programrii ce se pot rezolva mai simplu doar prin adresarea indirect. 134

Un asemenea exemplu poate reprezenta trimiterea unui set de date prin comunicaia serial, lucrnd cu buffere i indicatoare (ce vor fi discutate n continuare ntr-un capitol cu exemple), sau, un alt exemplu este tergerea unei pri a memoriei RAM (16 locaii) ca n urmtorul exemplu.

tergnd datele din registrul INDF se scrie n memorie la adresa dat de registrul FSR valoarea zero ce reprezint operaia NOP (no operation- nu se face nimic).

4.2.

Porturile microcontrolerului

Unii pini ai porturilor I/O sunt multiplexai i au o funcie alternativ asociat cu unul din perifericele dispozitivului. n general, cnd perifericul este activat, aceti pini nu mai pot fi folosii ca pini I/O de uz general ci pentru funcia destinat la perifericul ce este activat.

135

Registrul PORTA (ADRESA 05h) Registrul PORTA este registrul buffer de ieire a portului A. Atunci cnd se citete furnizeaz starea pinilor portului dac acetia au fost configurai ca intrri (n registrul TRISA) iar cnd se scrie, se scrie n registrul buffer PORTA care se transmite la pini dac acetia au fost configurai ca ieiri (n registrul TRISA). Operaia de scriere n registrul PORTA este o operaie read-modify-write, adic se citesc pinii portului, se modific valorile i se scrie n latch port. Bit 7 Bit 6 bit 5 RA4/T0CKI bit 4 RA3 bit 3 RA2 bit 2 RA1 bit 1 RA0 bit 0

Registrul TRISA (ADRESA: 85h) Registrul TRISA este destinat pentru stabilirea direciei pinilor portului A. Dac se scrie 0 ntr-un bit al acestui registru, pinul corespunztor este setat ca ieire iar dac se scrie 1 este setat ca intrare. TRISA4 TRISA3 Bit 7 Bit 6 bit 5 bit 4 bit 3 Exemplu pentru iniializarea portului A: TRISA2 bit 2 TRISA1 bit 1 TRISA0 bit 0

BCF STATUS, RP0 ; CLRF PORTA ;Initialize PORTA bz clearing output data latches BSF STATUS, RP0 ;Select Bank 1 MOWLW 0X0F ;Value used to initialize data direction MOWWF TRISA ;Set RA<3>0> as imputs RA4 as output ;TRISA<7:5> are always read as '0'

Registrul PORTB (ADRESA 06h) Registrul PORTB este registrul buffer de ieire a portului B. Atunci cnd se citete, furnizeaz starea pinilor portului dac acetia au fost configurai ca intrri (n registrul TRISB) iar cnd se scrie, se scrie n registrul buffer PORTB care se transmite la pini dac acetia au fost configurai ca ieiri (n registrul TRISB). Operaia de scriere n registrul PORTB este o operaie read-modify-write, adic se citesc pinii portului, se modific valorile i se scrie n latch port. Fiecare pin al portului B are o sarcin intern cuplat la sursa de alimentare. Cu ajutorul unui singur bit de control (bitul /RBPU - bitul 7 din registrul OPTION) sarcinile pot fi conectate dac acest bit este ters. Sarcinile sunt decuplate automat dac pinii portului sunt configurai ca ieire. De asemenea sarcina este decuplat la resetul de alimentare al dispozitivului (Power-On Reset). Patru din pinii portului B, RB7:RB4 au asociat o ntrerupere la schimbare (vezi registrul INTCON). Numai pinii configurai ca intrri permit aceast ntrerupere. O astfel de ntrerupere poate scoate dispozitivul din modul SLEEP. Utilizatorul, n subprogramul de servire a ntreruperii poate terge ntreruperea n modul urmtor: a) orice scriere a PORTB. Aceast aciune va ncheia condiia de schimbare; b) tergerea fanionului RBIF. 136

O condiie de schimbare va continua s seteze fanionul RBIF. Citind PORTB se va ncheia condiia de schimbare i fanionul RBIF va fi ters. RB7(1) Bit 7
(1) (2)

RB6(2) RB5 Bit 6 bit 5

RB4 bit 4

RB3 bit 3

RB2 bit 2

RB1 bit 1

RB0/INT bit 0

Serial programming data Serial programming clok

Registrul TRISB (ADRESA: 86h) Registrul TRISB este destinat pentru stabilirea direciei pinilor portului B. Dac se scrie 0 ntr-un bit al acestui registru, pinul corespunztor este setat ca ieire iar dac se scrie 1 este setat ca intrare. TRISB7 Bit 7 TRISB6 Bit 6 TRISB5 bit 5 TRISB4 bit 4 TRISB3 bit 3 TRISB2 bit 2 TRISB1 bit 1 TRISB0 bit 0

Exemplu, iniializarea portului B:


BCF CLRF latches BSF MOVLW 0xCF MOPVWF STATUS, RP0 ; PORTB ;Initialize PORTB bz clearing output data

STATUS, RP0 ;Select Bank 1 ;Value used to initialize data direction TRISB ;Set RB<3:0> as inputs, RB<5:4> as outputs ;RB<7:6> as inputs

4.3.

Setul de instruciuni a unitilor centrale de tip RISC PIC12, PIC16 i PIC18

Fiecare instruciune reprezint un cuvnt de 14 bii compus dintr-un cod de instruciune (OPCODE) care specific tipul de instruciune i unul sau mai muli operanzi. Setul de instruciuni al microcontrolerelor PIC este prezentat n tabelul 4.1 care cuprinde instruciunile orientate pe octet (byte-oriented), pe bit (bit-oriented) i operaiile bazate pe numere i de control (literal and control operations). Pentru instruciunile orientate pe octet 'f' reprezint simbolizarea unui registru (a file register) folosit de instruciune iar 'd' este folosit pentru a simboliza destinaia. Simbolurile de registru vor arta care din registre sunt folosite de instruciune. Simbolul pentru destinaie arat unde se plaseaz rezultatul operaiei. Dac 'd' este zero atunci rezultatul este plasat n registrul W. Dac 'd' este unu atunci rezultatul este plasat n registrul specificat de instruciune. La instruciunile orientate pe bit, 'b' reprezint simbolul unui bit care indic bitul afectat de operaie pe cnd 'f' simbolizeaz adresa registrului unde este localizat bitul. Pentru operaii cu constante (literal = numr) i de control 'k' reprezint o constant sau un numr pe 8 sau 11 bii.

137

TABELUL 4.1. Setul de instruciuni. Mnemonic, Description operands BYTE-ORIENTED FILE REGISTER OPERATIONS ADDWF f, d Add W and f ANDWF f, d AND W with f CLRF f Clear f CLRW Clear W COMF f, d Complement f DECF f, d Decrement f DECFSZ f, d Decrement f, Skip if 0 INCF f, d Increment f INCFSZ f, d Increment f, Skip if 0 IORWF f, d Inclusive OR W with f MOVF f, d Move f MOVWF f Move W to f NOP No Operation RLF f, d Rotate Left f through Carry RRF f, d Rotate Right f through Carry SUBWF f, d Subtract W from f SWAPF f, d Swap nibbles in f XORWF f, d Exclusive OR W with f BIT-ORIENTED FILE REGISTER OPERATIONS BCF f, b Bit Clear f BSF f, b Bit Set f BTFSC f, b Bit Test f, Skip if Clear BTFSS f, b Bit Test f, Skip if Set LITERAL AND CONTROL OPERATIONS ADDLW k Add literal and W ANDLW k AND literal with W CALL k Call subroutine CLRWDT Clear Watchdog Timer GOTO k Go to address IORLW k Inclusive OR literal with W MOVLW k Move literal to W RETFIE Return from interrupt RETLW k Return with literal in W RETURN Return from Subroutine SLEEP Go into standby mode SUBLW k Subtract W from literal XORLW k Exclusive OR literal with W
ADDLW Add Literal and W Sintaxa: [ etichet] ADDLW k Operand: 0 k 255 Operaia: (W) + k (W) Bistabili de stare modificai: C, DC, Z Descriere: la coninutul registrului W este adunat valoarea pe opt bii (literalul) *k* iar rezultatul este plasat n registrul W.

138

ADDWF Add W and f Sintaxa: [ etichet] ADDWF f,d Operanzi: 0 f 127 d [0,1] Operaia: (W) + (f) (destinaie) Bistabili de stare modificai: C, DC, Z Descriere: se adun coninutul registrului W cu registrul *f*. Dac *d* este *0*, rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f* ANDLW AND Literal with W Sintaxa: [ etichet] ANDLW k Operand: 0 k 255 Operaia: (W) .AND. (k) (W) Bistabili de stare modificai: Z Descriere: se efectueaz operaia I ntre coninutul registrului cu valoarea numeric pe opt bii (literalul) *k*. Rezultatul este plasat n registrul W. ANDWF AND W with f Sintaxa: [ etichet] ANDWF f,d Operanzi: 0 f 127 d [0,1] Operaia: (W) .AND. (f) (destinaie) Bistabili de stare modificai: Z Descriere: se efectueaz operaia I ntre registrul W i registrul *f*. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. BCF Bit Clear f Sintaxa: [ etichet] BCF f,b Operanzi: 0 f 127 0b7 Operaia: 0 (f<b>) Bistabili de stare modificai: nici unul. Descriere: bitul *b* din registrul *f* este ters. BSF Bit Set f Sintaxa: [ etichet] BSF f,b Operanzi: 0 f 127 0b7 Operaia: 1 (f<b>) Bistabili de stare modificai: nici unul Descriere: bitul *b* din registrul *f* este setat. BTFSS Bit Test f, Skip if Set Sintaxa: [ etichet] BTFSS f,b Operanzi: 0 f 127 0b<7 Operaia: sare dac (f<b>) = 1 Bistabili de stare modificai: nici unul. Descriere: dac bitul *b* din registrul *f* este zero, se execut instruciunea urmtoare. Dac bitul *b* din registrul *f* este unu atunci instruciunea urmtoare este srit i se execut o instruciune NOP obinndu-se o instruciune de dou cicluri (2TCY). BTFSC Bit Test, Skip if Clear Sintaxa: [ etichet] BTFSC f,b Operanzi: 0 f 127 0b7 Operaia: sare dac (f<b>) = 0

139

Bistabili de stare modificai: nici unul. Descriere: dac bitul *b* din registrul *f* este unu, se execut instruciunea urmtoare. Dac bitul *b* din registrul *f* este zero atunci instruciunea urmtoare este srit i se execut o instruciune NOP obinndu-se o instruciune de dou cicluri (2TCY). CALL Call Subroutine Sintaxa: [ etichet ] CALL k Operand: 0 k 2047 Operaia: (PC)+ 1 TOS, k PC<10:0>, (PCLATH<4:3>) PC<12:11> Bistabili de stare modificai: nici unul. Descriere: apeleaz o subrutin. Mai nti adresa de rentoarcere (PC+1) este salvat n stiv. Cei unsprezece bii ai adresrii imediate sunt ncrcai n biii PC <10:0>. Biii cei mai semnificativi ai registrului PC sunt ncrcai din PCLATH. Instruciunea CALL este o instruciune de dou cicluri. CLRF Clear f Sintaxa: [ etichet] CLRF f Operand: 0 f 127 Operaia: 00h (f) 1Z Bistabili de stare modificai: Z Descriere: Coninutul registrului *f* este ters iar bistabilul Z este setat. CLRW Clear W Sintaxa: [ etichet ] CLRW Operand: nici unul. Operaia: 00h (W) 1Z Bistabili de stare modificai: Z Descriere: registrul W este ters iar bistabilul Z este setat. CLRWDT Clear Watchdog Timer Sintaxa: [ etichet ] CLRWDT Operand: nici unul Operaia: 00h WDT 0 WDT prescaler, 1 TO 1 PD Bistabili de stare modificai: TO, PD Descriere: instruciunea CLRWDT reseteaz Watchdog Timer. De asemenea este resetat prescaler-ul WDT. Bistabilii de stare TO i PD sunt setai. COMF Complement f Sintaxa: [ etichet ] COMF f,d Operanzi: 0 f 127 d [0,1] Operaia: (f) (destinaie) Bistabili de stare modificai: Z Descriere: coninutul registrului *f* este complementat. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. DECF Decrement f Sintaxa: [ etichet] DECF f,d Operanzi: 0 f 127 d [0,1]

140

Operaia: (f) - 1 (destinaie) Bistabili de stare afectai: Z Destinaie: Decrementeaz registrul *f*. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. DECFSZ Decrement f, Skip if 0 Sintaxa: [ etichet ] DECFSZ f,d Operanzi: 0 f 127 d [0,1] Operaia: (f) - 1 (destinaie); sare dac rezultatul = 0 Bistabili de stare afectai: nici unul Descriere: Coninutul registrului *f* este decrementat. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. Dac rezultatul este *1*, instruciunea urmtoare este executat. Dac rezultatul este *0* atunci se execut o instruciune NOP obinndu-se o instruciune de dou cicluri (2TCY). GOTO Unconditional Branch Sintaxa: [ etichet ] GOTO k Operands: 0 k 2047 Operaia: k PC<10:0> PCLATH<4:3> PC<12:11> Bistabili de stare afectai: nici unul Descriere: instruciunea GOTO este o instruciune de salt necondiionat. Valoarea imediat de unsprezece bii este ncrcat n biii PC <10:0>. Cei mai semnificativi bii ai registrului PC sunt ncrcai din PCLATH<4:3>. GOTO este o instruciune de dou cicluri. INCF Increment f Sintaxa: [ etichet ] INCF f,d Operands: 0 f 127 d [0,1] Operaia: (f) + 1 (destinaie) Bistabili de stare afectai: Z Descriere: coninutul registrului *f* este incrementat. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. INCFSZ Increment f, Skip if 0 Sintaxa: [ etichet ] INCFSZ f,d Operands: 0 f 127 d [0,1] Operaia: (f) + 1 (destinaie), sare dac rezultatul = 0 Bistabili de stare afectai: Nici unul Descriere: Coninutul registrului *f* este incrementat. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. Dac rezultatul este *1* atunci se execut instruciunea urmtoare. Dac rezultatul este *0* atunci se execut o instruciune NOP obinndu-se o instruciune pe dou cicluri (2TCY). IORLW Inclusive OR Literal with W Sintaxa: [ etichet ] IORLW k Operand: 0 k 255 Operaia: (W) .OR. k (W) Bistabili de stare afectai: Z Descriere: se realizeaz operaia OR ntre coninutul registrului W i valoarea pe opt bii (literalul) *k*. Rezultatul este plasat n registrul W. IORWF Inclusive OR W with f

141

Sintaxa: [ etichet ] IORWF f,d Operands: 0 f 127 d [0,1] Operaia: (W) .OR. (f) (destination) Bistabili de stare afectai: Z Descriere: se realizeaz operaia SAU ntre registrul W cu registrul *f*. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. MOVF Move f Sintaxa: [ etichet ] MOVF f,d Operanzi: 0 f 127 d [0,1] Operaia: (f) (destinaie) Bistabili de stare afectai: Z Descriere: coninutul registrului *f* este transferat la destinaie n funcie de valoarea lui *d*. Dac d = 0 atunci destinaia este registrul W iar dac d = 1 atunci destinaia este nsui registrul *f*. Situaia n care d = 1 este util la testarea registrului *f* cnd n urma operaiei se poziioneaz bistabilul Z. MOVLW Move Literal to W Sintaxa: [ etichet ] MOVLW k Operand: 0 k 255 Operaia: k (W) Bistabili de stare afectai: nici unul Descriere: valoarea pe opt bii este ncrcat n registrul *f*. MOVWF Move W to f Sintaxa: [ etichet ] MOVWF f Operand: 0 f 127 Operaia: (W) (f) Bistabili de stare afectai: nici unul Descriere: coninutul registrului W este transferat n registrul *f*. NOP No Operation Sintaxa: [ etichet ] NOP Operand: nici unul Operaia: nici o operaie. Bistabili de stare afectai: nici unul Descriere: nu se efectueaz nici o operaie. RETFIE Return from Interrupt Sintaxa: [ etichet ] RETFIE Operand: Nici unul Operaia: TOS PC, 1 GIE Bistabili de stare afectai: nici unul RETLW Return with Literal in W Sintaxa: [ etichet ] RETLW k Operand: 0 k 255 Operaia: k (W); TOS PC Bistabili de stare afectai: nici unul Descriere: registrul W este ncrcat cu valoarea pe opt bii (literalul) *k*. Contorul de program este ncrcat cu valoarea din vrful stivei (adresa de rentoarcere). Instruciunea dureaz dou cicluri.

142

RETURN Return from Subroutine Sintaxa: [ etichet ] RETURN Operand: Nici unul Operaia: TOS PC Bistabili de stare afectai: nici unul Descriere: rentoarcere din subprogram. Vrful stivei (TOS Top of Stack) este ncrcat n registrul contor de program PC. Instruciunea dureaz dou cicluri. RLF Rotate Left f through Carry Sintaxa: [ etichet ] RLF f,d Operanzi: 0 f 127 d [0,1] Operaia: vezi descrierea. Bistabili de stare afectai: C Descriere: coninutul registrului *f* este rotit spre stnga un bit prin bistabilul Carry. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. RRF Rotate Right f through Carry Sintaxa: [ etichet ] RRF f,d Operands: 0 f 127 d [0,1] Operaia: vezi descrierea. Bistabili de stare afectai: C Descriere: coninutul registrului *f* este rotit spre dreapta un bit prin bistabilul Carry. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. SLEEP Sintaxa: [ etichet ] SLEEP Operand: nici unul Operaia: 00h WDT, 0 WDT prescaler, 1 TO, 0 PD Bistabili de stare afectai: TO, PD Descriere: bitul de stare Power-Down PD este ters. Bitul de stare Time-Out este setat. Watchdog Timer i prescaler-ul sunt teri. Procesorul este pus n modul SLEEP cu oscilatorul oprit. SUBLW Subtract W from Literal Sintaxa: [ etichet ] SUBLW k Operand: 0 k 255 Operaia: k - (W) (W) Bistabili de stare afectai: C, DC, Z Descriere: coninutul registrului W este sczut (prin metoda complementului fa de doi) din valoarea de opt bii (literalul) *k*. Rezultatul este pus n registrul W. SUBWF Subtract W from f Sintaxa: [ etichet ] SUBWF f,d Operanzi: 0 f 127 d [0,1] Operaia: (f) - (W) (destinaie) Bistabili de stare afectai: C, DC, Z Descriere: coninutul registrului W este sczut (prin metoda complementului fa de doi) din valoarea registrului *f*. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*.

143

Bistabilul C este 1 cnd rezultatul este pozitiv sau zero si zero cnd rezultatul este negativ. SWAPF Swap Nibbles in f Sintaxa: [ etichet ] SWAPF f,d Operanzi: 0 f 127 d [0,1] Operaia: (f<3:0>) (destinaie<7:4>), (f<7:4>) (destinaie<3:0>) Bistabili de stare afectai: nici unul Descriere: cei mai semnificativi patru bii ai registrului *f* sunt schimbai cu cei mai puin semnificativi patru bii (nibble) ai registrului *f*. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*. XORLW Exclusive OR Literal with W Sintaxa: [ etichet] XORLW k Operand: 0 k 255 Operaia: (W) .XOR. k (W) Bistabili de stare afectai: Z Descriere: se execut operaia XOR (SAU EXCLUSIV) ntre valoarea registrului W i valoarea pe opt bii (literalul) *k*. Rezultatul este plasat n registrul W. XORWF Exclusive OR W with f Sintaxa: [ etichet] XORWF f,d Operanzi: 0 f 127 d [0,1] Operaia: (W) .XOR. (f) (destinaie) Bistabili de stare afectai: Z Descriere: se execut operaia XOR (SAU EXCLUSIV) ntre valoarea registrului W i valoarea registrului *f*. Dac *d* este *0* atunci rezultatul este stocat n registrul W iar dac *d* este *1* rezultatul este stocat n registrul *f*.

Not: pentru a menine compatibilitatea cu produsele PIC16CXX viitoare nu trebuie folosite instruciunile OPTION i TRIS.

4.4.

Exemple de programe n limbaj de asamblare

n acest paragraf se vor prezenta cteva programe simple, scrise n limbaj de asamblare, pentru microcontrolerele PIC12, PIC16 sau PIC18. 4.4.1. Iniializarea unei zone de memorie RAM Un exemplu de adresare indirect folosit la tergerea unei pri a memoriei RAM (16 locaii) ca n urmtorul exemplu.
Movlw Hovwf LOOP clrf Incf Btfss Goto CONTINUE : OxOC FSR INDF FSR FSR,4 loop ; ; ; ; ; ; initialization of starting address FSR indicates address OxOC INDF = 0 address = initial address + 1 are all locations erased no, go through a loop again

; yes, continue with program

144

tergnd datele din registrul INDF se scrie n memorie la adresa dat de registrul FSR valoarea zero ce reprezint operaia NOP (no operation- nu se execut nimic). 4.4.2. Salvarea i restaurarea registrelor (echivalentul instruciunilor PUSH i POP) Datorit simplitii i folosirii frecvente, aceste pri ale programului pot fi fcute ca macro-uri. n urmtorul exemplu, coninuturile registrelor W i STATUS sunt memorate n variabilele W_TEMP i STATUS_TEMP nainte de rutina de ntrerupere. La nceputul rutinei PUSH trebuie s verificm bancul selectat n prezent pentru c W_TEMP and STATUS_TEMP nu se gsesc n bancul 0. Pentru schimbul de date ntre aceste registre, instruciunea SWAPF se folosete n loc de MOVF pentru c nu afecteaz starea biilor registrului STATUS. Exemplul este un program asamblor pentru urmtorii pai: 1. Testarea bancului curent 2. Stocarea registrului W indiferent de bancul curent 3. Stocarea registrul STATUS n bancul 0 4. Executarea rutinei de ntrerupere pentru procesul de ntrerupere (ISR) 5. Restaureaz registrul STATUS 6. Restaureaz registrul W Dac mai sunt i alte variabile sau registre ce trebuie stocate, atunci ele trebuie s fie pstrate dup stocarea registrului STATUS (pasul 3) i aduse napoi, nainte ca registrul STATUS s fie restaurat (pasul 5). Macro-urile realizate, pot fi folosite pentru scrierea de noi macro-uri.
push macro movwf swapf BANK1 swapf movwf BANKO swapf movwf endm macro swapf movwf BANK1 swapf movwf BANKO swapf endm W_Temp W_Temp,F OPTION_REGJ,W Option_Temp STATUS,W Stat_Temp Stat_Temp,W STATUS Option_Temp,W OPTION_REG W_Temp,W ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; W_Tem p <- W Swap them macro for switching to Bankl W <- OPTION_REG Option_Temp <- W macro for switching to Bank0 W <- STATUS Stat_Temp <- W End of push macro W <- Stat_Temp STATUS <- W Macro for switching to Bankl W <- Option Temp OPTIOW_REG <- W Macro for switching to BankO W <- W_Temp End of a pop macro

pop

4.4.3. Testarea coninutului unui registru Se testeaz dac o locaie de memorie este egal cu o anumit valoare. 145

movf sublw btfsc goto goto

timp_100us,w;se citeste locaia de memorie timp_100us in w D'10' ;se testeaza daca valoarea este egala cu 10 STATUS, Z msecunda ;este egala cu 10 MAIN1 ;nu este egala cu 10

4.4.4. Conversie binar-ASCII Se convertete un numr binar ntr-un numar ASCII.


movlw b'00000111' ;un numar oarecare intre 0 si 9 call TABLE ;se apeleaza subprogramul de conversie movwf r0 ;caracterul ASCII corespunzator ;numarului este salvat in memoria r0 goto main TABLE addwf PCL,1 ; Number 0-9 DT "0123456789" ;directiva DT (Define Table) genereaza un sir de instructiuni ;retlw k, cite una pentru fiecare termen al sirului ;directiva este folosita la generarea tabelelor de date pentru ;unitatile centrale din familia PIC 12/16

4.4.5. Afiarea unui ir pe un display LCD Se prezint un program complet de afiare a unui ir pe un display LCD.
list p=16F877A ; list directive to define processor #include <p16F877A.inc>; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_ON & _DEBUG_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm ;file. ; The lables following the directive are located in the respective ;.inc file. ; See respective data sheet for additional information on ;configuration word. ;***** VARIABLE DEFINITIONS w_temp 0x70 EQU status_temp EQU 0x71 ; variable used for context saving ; variable used for context saving

CBLOCK 0x20 ; RAM in bank0 ;variabile necesare pentru afisare LCD BUFFER0,BUFFER1 ;variabile pentru temporizari XX,YY ENDC ;Resursele folosite: ;PORTB la care se folosesc pinii RB2 la RB7: RB7:RB4 magistrala de ;date la D7:D4 a LCD, RB3 pinul RS a LCD, RB2 pinul enable a LCD, ;deoarece nu se fac citiri din LCD pinul R/W este pus la masa. Acest ;pin poate fi pus la RB1 si RB1 comutat la zero pentru scriere

146

;in LCD sau in unu pentru citire din LCD. De asemenea D3:D0 a LCD se ;leaga la masa. ;Temporizarea este facuta soft. ;********************************************************************* ORG 0x000 ; processor reset vector clrf PCLATH ; ensure page bits are cleared goto main ; go to beginning of program ORG 0x004 movwf w_temp movf STATUS,w movwf status_temp ; ; ; ; interrupt vector location save off current W register contents move status register into W register save off contents of STATUS register

; isr code can go here or be located as a call subroutine elsewhere movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ;PROGRAMUL PRINCIPAL main CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL INIT_LCD ; Setup LCD "T" ; Setup message WR_LCD_DATA "e" WR_LCD_DATA "s" WR_LCD_DATA "t" WR_LCD_DATA " " WR_LCD_DATA "L" WR_LCD_DATA "C" WR_LCD_DATA "D" WR_LCD_DATA

main1

goto main1

;SUBPROGRAMELE ;+++++++++++++++++++++++++++ LCD +++++++++++++++++++++++++++++++++++ ;Subprogramele pentru LCD sunt alcatuite din: ;Subprogram INIT_LCD ;subprogramul de initializare a LCD ;in acest subprogram se seteaza iesirile PORTB RB7-RB2 ca iesiri iar ;RB1-RB0 ca intrari ;nota: pentru LCD sunt necesare numai iesirile RB7-RB2

147

;Subprogram FUNCTION_INIT - necesar INIT_LCD ;in acest subprogram se transmite comanda 0x33 = 00110011 ;si apoi comanda 0x32 = 00110010 catre LCD ;acest lucru seteaza afisarea cu date pe 4 biti ;Subprogram FUNCTION_SET - necesar INIT_LCD ;seteaza LCD cu date pe 4 biti si 2 rinduri ;Subprogram ENTRY_MODE ;seteaza LCD sa miste cursorul spre dreapta ;Subprogram DISPLAY_CTRL ;seteaza LCD: Display ON, Cursor OFF, pilpiire OFF ;Subprogram WR_LCD_DATA ;subprogramul scrie o data in LCD. Data in registrul w ;transmite succesiv mai intii cei mai semnificativi 4 biti ;si apoi cei mai putini semnificativi 4 biti ;Subprogram WR_LCD_CMD ;subprogramul scrie o comanda in LCD. Comanda in registrul w. ;transmite succesiv mai intii cei mai semnificativi 4 biti ;si apoi cei mai putini semnificativi 4 biti ;Subprogramul WR_LCD_CMD2 ;similar cu WR_LCD_CMD dar cu pemporizari mai mari ;se foloseste pentru comenzi ce necesita asteptari mai lungi ;Subprogram MASK_BIT_CMD ;in aceasta subrutina se seteaza RS si E pentru comenzi ;si se trimite cuvintul spre LCD ;de asemenea se comuta E ;Denumirea e improprie pentru ca de fapt nu se mascheaza nimic ;Subprogramul MASK_BIT_DATA ;in aceasta subrutina se seteaza RS si E pentru date ;si se trimite cuvintul spre LCD ;de asemenea se comuta E ;Denumirea e improprie pentru ca de fapt nu se mascheaza nimic ;Subprogramul CLEAR_SCREEN ;sterge afisajul LCD ;Subprogramul RETURN_HOME ;duce cursorul home ;Subprogramul DISPLAY_ON ;seteaza display LCD on ;Subprogramul SET_POSITION ;seteaza pozitia in DDRAM ;Subprogramul DELAY15U ;intirziere 15,05 microsecunde ;Subprogramul DELAY45U ;intirziere ~45 microsecunde ;Subprogramul DELAY617U

148

;intirziere 617,2 microsecunde ;Subprogramul DELAY5M ;intirziere ~5 milisecunde ;===================================================================== #DEFINE #DEFINE #DEFINE #DEFINE #DEFINE LCD_DATA_BUS PORTB ; RB7:RB4 = Data bus LOW_RS BCF PORTB,3 ; RB3 = RS pin HIGH_RS BSF PORTB,3 LOW_E BCF PORTB,2 ; RB2 = enable pin HIGH_E BSF PORTB,2

CONSTANT FUNCTION_VALUE = B'00101000' ; LCD command ;Functie: 4 biti 2 linii CONSTANT ENTRY_VALUE = B'00000110' ; LCD command ;cursorul se misca spre dreapta CONSTANT DISPLAY_VALUE = B'00001100' ; LCD command ;Control display: Display ON, Cursor OFF, pilpiire OFF ;===================================================================== ; aceste comenzi sunt preluate din Carte PIC capitolul 6 ; comenzile LCD ; ; CONSTANT LCDEM8 = b00110000 ;mod 8 biti, 1 linie ; constant = b'00111000' ;mod 8 biti, 2 linii ; CONSTANT LDCEM4 = b00100000 ;mod 4 biti, 1 linie ; CONSTANT = b'00101000' ;mod 4 biti, 2 linii ; CONSTANT LCDDZ = b10000000 ;scrie 0 in DDRAM ;trebuie dat inainte adresa din DDRAM unde se scrie ; comenzi standard pentru initializarea LCD ; CONSTANT LCD2L = b00101000 ;Functie: 4 biti 2 linii ;=============FUNCTION_VALUE din programul folosit aici ; CONSTANT LCDCONT = b00001100;Control display: Display ON ;Cursor OFF, pilpiire OFF ;=============DISPLAY_VALUE din programul folosit aici ; CONSTANT LCDSH = b00101000 ;Display mode: AutoInc cursor ;NoDisplayAutoShift ;se observa ca este acelasi cu LCD2L ; Comenzi LCD standard ;sterge display, ;reseteaza cursorul ; CONSTANT LCDCH = b00000010 ;cursor home ; CONSTANT LCDCR = b00000110 ;cursorul se misca spre ;dreapta ;=============ENTRY_VALUE din programul folosit aici ; CONSTANT LCDCL = b00000100;cursorul se misca spre stinga ; CONSTANT LCDSL = b00011000;deplasare continut display spre ;stinga ; CONSTANT LCDSR = b00011100;deplasare continut display spre ;dreapta ;de fapt aici LCDL1 este adresa de inceput a primei linii iar LCDL2 ;este adresa de inceput a celei de-a doua linii. Vezi mai jos. ; CONSTANT LCDL1 = b10000000 ;selecteaza linia 1 ; CONSTANT LCDCLR = b00000001

149

CONSTANT

LCDL2 = b11000000

;selecteaza linia 2

;===================================================================== ;Adresa DDRAM ;Afisajul LCD are 8x80 de pixeli si afiseaza 2x16 caractere. ;Memoria DDRAM are 80 de octeti corespunzator pixelilor. 80/5=16 ;Caracterele sunt afisate in matrici de 5x7 pixeli sau 5x10. ;Pe doua linii caracterele nu pot fi afisate decit ca 5x7 pixeli. ;(ultimul rind din matrice este pentru cursor) ;Caracterele sunt scrise succesiv in memoria DDRAM ;Adresele memoriei DDRAM sunt intre 80h si A7h pentru prima linie sau ;C0h la E7 pentru a doua linie. ;Structura adresei este: 1, linie (un bit), adresa (6 biti). ;80h = 10000000b - adresa 0 prima linie ;A7h = 10100111b - adresa 39 prima linie ;C0h = 11000000b - adresa 0 a doua linie ;E7h = 11100111b - adresa 39 a doua linie ;in memoria DDRAM se scriu coduri ASCII - de ce sunt atunci 40 de ;adrese pe fiecare linie? ; ;Distinctia dintre coduri ASCII de afisat (date) si comenzi se face de catre registrul RS ;0 = instructiuni (comenzi) ;1 = date ; INIT_LCD ;subprogramul de initializare a LCD ;in acest subprogram se seteaza iesirile PORTB RB7-RB2 ca iesiri iar ;RB1-RB0 ca intrari ;nota: pentru LCD sunt necesare numai iesirile RB7-RB2 BSF STATUS,RP0 ; Bank 1 MOVLW B'00000011' ; RB7-RB2 as output MOVWF TRISB BCF STATUS,RP0 ; Bank 0 CALL DELAY5M ; Delay > 15 millisecond CALL DELAY5M CALL DELAY5M CALL DELAY5M ; 4 bit initialization CALL FUNCTION_INIT CALL FUNCTION_SET ; date pe 4 biti si 2 rinduri CALL ENTRY_MODE ;cursor spre dreapta CALL DISPLAY_CTRL ; Display ON, Cursor OFF, pilpiire OFF CALL CLEAR_SCREEN ; Clear display RETURN FUNCTION_INIT ;in acest subprogram se transmite comanda 0x33 = 00110011 ;si apoi comanda 0x32 = 00110010 catre LCD ;acest lucru seteaza afisarea cu date pe 4 biti MOVLW 0x33 CALL WR_LCD_CMD2 MOVLW 0x32 GOTO WR_LCD_CMD FUNCTION_SET ;seteaza LCD cu date pe 4 biti si 2 rinduri MOVLW FUNCTION_VALUE GOTO WR_LCD_CMD

150

ENTRY_MODE ;seteaza LCD sa miste cursorul spre dreapta MOVLW ENTRY_VALUE GOTO WR_LCD_CMD DISPLAY_CTRL ;seteaza LCD: Display ON, Cursor OFF, pilpiire OFF MOVLW DISPLAY_VALUE GOTO WR_LCD_CMD WR_LCD_DATA ;subprogramul scrie o data in LCD. Data in registrul w. ;transmite succesiv mai intii cei mai semnificativi 4 biti ;si apoi cei mai putini semnificativi 4 biti MOVWF BUFFER0 ; Write high nibble CALL MASK_BIT_DATA ; seteaza si RS si E care se ;transmit la LCD pentru data HIGH_E SWAPF BUFFER0,0 ; Write low nibble CALL MASK_BIT_DATA HIGH_E CALL DELAY45U ; Delay 40 microsecond RETURN WR_LCD_CMD ;subprogramul scrie o comanda in LCD. Comanda in registrul w. ;transmite succesiv mai intii cei mai semnificativi 4 biti ;si apoi cei mai putini semnificativi 4 biti MOVWF BUFFER0 ; Write high nibble CALL MASK_BIT_CMD ; seteaza si RS si E care se ;transmit la LCD pentru comanda HIGH_E SWAPF BUFFER0,0 ; Write low nibble CALL MASK_BIT_CMD CALL DELAY45U ; Delay 40 microsecond HIGH_E RETURN WR_LCD_CMD2 ;similar cu WR_LCD_CMD dar cu pemporizari mai mari ;se foloseste pentru comenzi ce necesita asteptari mai lungi MOVWF BUFFER0 ; Write high nibble CALL MASK_BIT_CMD CALL DELAY5M HIGH_E SWAPF BUFFER0,0 ; Write low nibble CALL MASK_BIT_CMD CALL DELAY45U ; Delay > 100 microsecond CALL DELAY45U CALL DELAY45U HIGH_E RETURN MASK_BIT_CMD ;in aceasta subrutina se seteaza RS si E pentru comenzi ;si se trimite cuvintul spre LCD ;de asemenea se comuta E MOVWF BUFFER1

151

LOW_RS BCF BUFFER1,3 ; For RS = 0 BSF BUFFER1,2 ; For E = 1 MOVFW BUFFER1 MOVWF LCD_DATA_BUS NOP LOW_E ; Enable pulse RETURN MASK_BIT_DATA ;in aceasta subrutina se seteaza RS si E pentru date ;si se trimite cuvintul spre LCD ;de asemenea se comuta E MOVWF BUFFER1 HIGH_RS BSF BUFFER1,3 ; For RS = 1 BSF BUFFER1,2 ; For E = 1 MOVFW BUFFER1 MOVWF LCD_DATA_BUS NOP LOW_E ; Enable pulse RETURN CLEAR_SCREEN ;sterge afisajul LCD MOVLW B'00000001' ; Clear LCD CALL WR_LCD_CMD CALL DELAY5M RETURN RETURN_HOME ;duce cursorul home MOVLW B'00000010' CALL WR_LCD_CMD CALL DELAY5M RETURN DISPLAY_ON ;seteaza display LCD on MOVLW B'00001100' GOTO WR_LCD_CMD

; Return home

; Turn-on display

SET_POSITION ;seteaza pozitia in DDRAM GOTO WR_LCD_CMD ; Set DDRAM position

;++++++++++++++++++ DELAY SUBROUTINES ++++++++++++++++++++++++++++++++ DELAY15U ;intirziere 15,05 microsecunde MOVLW .25 ; Tdelay 15.05 microsecond MOVWF XX DECFSZ XX,1 GOTO $-1 RETURN DELAY45U ;intirziere ~45 microsecunde

152

MOVLW .74 MOVWF XX DECFSZ GOTO $-1 RETURN DELAY617U ;intirziere 617,2 CLRF XX MOVLW .4 MOVWF YY DECFSZ GOTO $-1 DECFSZ GOTO $-3 RETURN

; Delay ~45 microsecond XX,1

microsecunde ; Tdelay = 617.2 microsecond XX,1 YY,1

DELAY5M ;intirziere ~5 milisecunde CLRF XX ; Delay ~5 millisecond MOVLW .33 MOVWF YY DECFSZ XX,1 GOTO $-1 DECFSZ YY,1 GOTO $-3 RETURN END ; directive 'end of program'

153

BIBLIOGRAFIE
1. Arsinte Radu - Arhitecturi paralele i procesoare de semnal, Editura Politehnica, Timioara, 2000; 2. Athanasiu Irina, Panoiu Alexandru, - Microprocesoarele 8086, 286, 386, Editura TEORA, Bucureti, 1992; 3. Andronescu Gh., - Sisteme Digitale, Editura MatrixRom, Bucureti, 2002; 4. Baluta Gheorghe, - Circuite logice i structuri numerice. Proiectare i aplicaii. Editura MatrixRom, Bucureti, 2002; 5. Belega, D., - Placa de dezvoltare TMS320C5X DSK n aplicaii, Editura Politehnica, Timioara, 2002; 6. Blakeslee Thomas, - Proiectarea cu circuite logice MSI i LSI standard, EdituraTehnic, Bucureti, 1988; 7. Bogdanov Ivan, - Microprocesorul n comanda acionrilor electrice, Editura FACLA, Timioara, 1989; 8. Borcoci A. i col. - Arhitectura Microprocesoarelor Media publishing 1995; 9. Capatina Octavian, - Proiectarea cu microcalculatoare integrate, Editura Dacia, Cluj, 1992; 10. Cristian Lupu, tefan Stncescu, - Microprocesoare. Circuite. Proiectare, Editura Militara, Bucureti, 1986; 11. Dancea Ioan, - Microprocesoare. Arhitectura intern, programare, aplicaii. Editura Dacia, Cluj-Napoca, 1979; 12. Davidoviciu A., s.a., - Minicalculatoarele i microcalculatoarele n conducerea proceselor industriale, Editura Tehnic, Bucureti, 1983; 13. Douglas F. Elliott, - Handbook of Digital Signal Processing: Engineering Applications, Academic Press, 1987; 14. Dragu Ion, Iosif Ion-Mihail - Prelucrarea numeric a semnalelor discrete n timp, Editura Militar, Bucureti, 1985; 15. Driscoll F.F., Coughlin R.F., Villanucci R.S. - Data Acquisition and Process Control, Prentice Hall, 2000; 16. Dumortier Dominique, - Digital/Analog and Analog/Digital conversion Handbook, Motorola, 1990; 17. Graham., I., King, T. - The Transputer Handbook, Prentice Hall Ltd., 1989; 18. Grover Dale, John R. - Digital Signal Processing and the Microcontroller, Prentice Hall, 1999; 19. IEEE DSP Committee - Programs for Digital Signal Processing, IEEE Press, 1979; 20. Ionescu D. - Codificare i coduri, Editura Tehnic, Bucureti, 1981; 21. Lim J. S., Oppenheim A. V. - Advanced Topics in Signal Processing, Prentice Hall, 1988; 22. Lupu C., s.a. - Microprocesoare. Aplicaii. Editura Militar, Bucureti 1982; 154

23. Lupu Eugen, Miclea Tiberiu, Arsinte Radu - Procesoare de semnal - Generaia TMS320C2X - prezentare i aplicaii Ediura Promedia, Cluj-Napoca, 1995; 24. Marinescu D. Naicu S., - Microcontrolerul 80C32. Manual de utilizare. Editura Tehnic, Bucureti, 1998; 25. Marven, C., Ewers, G. A Simple Approach to Digital Signal Processing, Texas Instruments, 1993. 26. Musca Gh. - Programare n Limbaj de Asamblare Editura TEORA 1997, 27. Nigel P., - Cook A First Course In Digital Electronics, Pretice Hall, New Jersey,1999; 28. Oppenheim A. V., Schafer R. W., - Digital Signal Processing, Prentice-Hall, 1975; 29. Oppenheim A. V., Schafer R. W., - Discrete-Time Signal Processing, Prentice Hall, 1989; 30. Pop Eugen, s.a. - Metode n prelucrarea numeric a semnalelor, Editura FACLA, Timioara, 1989; 31. Proakis, G., Manolakis, D. G. - Digital Signal Processing. Principles, Algorithms and Applications, 3rd Edition, Prentice-Hall, 1996; 32. Puiu-Berizinu M., Rotar Dan An Optimal Control Method of the PWM Inverter used in Electrical Drives with Induction Motor - MIPRO99 CONFERENCE, IEEE Region 8, CROAIA 1999. 33. Puiu Berizinu Mihai, Rotar Dan Using DSP for PWM Inverter Command by the Generatrix Wave Sampling Principle, Conferina Naional de Acionri Electrice CNAE 2000, Iai, 12-14 octombrie 2000, publicat n Buletinul Institutului Politehnic Iai, Tomul XLVI (L), Fasc. 5, ISSN 0258-9109, pp. 72-77 34. Radu O., Sandulescu Gh., - Filtre numerice. Aplicaii, Editura Tehnic, Bucureti, 1979; 35. Rotar Dan - Harmonic analysis based on microcomputers, Efficiency, Cost, Optimization, Simulation and Environmental Aspects of Energy Systems and Processes Congress ECOS98, ISBN 2-905-267-29-1, Nancy, France, pp. 11731180, 1998. 36. Rotar Dan - Protection of the Microcomputer-based Pulse-Width Modulated Inverters, 17th International Conference on COMPUTERS IN TECHNICAL SYSTEMS, Proceedings Volume 2, ISBN 953-6042-57-6, pp. 67-70, CROAIA 1998. 37. Rotar Dan - Microcomputer-based electrical drives command with sound card, Conferina Naional de Acionri Electrice CNAE98, Craiova, 1998, pp. 165-168. 38. Rotar Dan, Ababei tefan - Determinarea consumului energetic prin contorizare numeric, Conferina Naional de Energetic Industrial, Bacu, 1998, Editura Plumb, ISBN 973-9362-16-8, pp. 170-173. 39. Rotar Dan Sisteme de msur digitale a energiei electrice Probleme de management i conservare a energiei, Craiova, ISBN 973-0-00917-1, pp. 21-28, 1999 40. Rotar Dan Programarea DSP, Conferina Naional de Energetic Industrial CNEI 2000 MILENIUM, 10-11 noiembrie 2000, Bacu, Editura ALMA MATER, ISBN 973-99703-4-6, pp. 84-87 41. Rotar Dan Regulator numeric pentru procesorul digital de semnal TMS320F240, Conferina Naional de Energetic Industrial CNEI 2000 MILENIUM, 10-11 noiembrie 2000, Bacu, Editura ALMA MATER, ISBN 973-99703-4-6, pp. 88-91 155

42. Rotar Dan, Ababei tefan, Sorin Popa, Communication system for dsp and PC compatible computer, Romanian Academy, Branch office of Iai, MCOM-8, 2002, ISSN 1224-7480, pp. 413-418. 43. Rotar Dan, Ababei tefan, DSP solution for experimental transistor characteristics plots, Romanian Academy, Branch office of Iai, MCOM-8, 2002, ISSN 1224-7480, pp. 419-421. 44. Rotar Dan, Petru Livini, Ababei tefan, Digital filtering with digital signal processing controller, Romanian Academy, Branch office, MCOM-9 vol. 2, 2003, ISSN 1224-7480, pp. 207-210. 45. Sheingold Danil H., Analog-digital conversion handbook, Analog Device, 1992; 46. Somnea Dan, Vldu Teodor, - Programarea in assembler. Editura Tehnic, Bucureti, 1992; 47. Stanasila Octavian, - Noiuni i tehnici de matematica discret, Editura tiintific i Enciclopedic, Bucureti, 1985; 48. Stanomir D., Stanasila O., - Metode matematice n teoria semnalelor, Editura Tehnic, Bucureti 1980; 49. Suciu Marcel, Popescu Dumitru, Ionescu Traian, - Microprocesoare, microcalculatoare i roboi n automatizri industriale, Editura Tehnic, Bucureti, 1986 50. Stearns S. D., - Digital Signal Analysis, Hayden Book, 1975; 51. Sztojanov I., .a. - De la poarta TTL la microprocesor vol I, II, Editura Tehnic, Bucureti, 1987; 52. Tnase Ady, Gitan V., - Familia de procesoare pentru prelucrarea numeric a semnalelor ADSP-21, Editura MatrixRom, Bucureti, 2004; 53. Toderean, G., .a. - Transputere i procesoare de semnal, Ed. Microinformatica, Cluj- Napoca, 1993; 54. Thomas L.Floyd - Digital Fundamentals, Pretice Hall, New Jersey,2000; 55. Toace Gh., - Introducere n microprocesoare, Editura tiintific i Enciclopedic, Bucureti, 1986; 56. Tocci Ronald J., Neal S. Widmer - Digital Systems, Pretice Hall, New Jersey,1998; 57. Toma L., - Sisteme de achiziie i prelucrarea numeric a semnalelor, Editura de Vest, Timioara.1996; 58. Zoican Sorin, - Joint Time-Frequency Adaptive Echo Canceller with Digital Signal Processor, Proceedings of MELECON'2000, May 29-31, 2000, Cyprus, pp. 295300; 59. Zoican Sorin, - Effect of LMS Decorrelated Algorithm on the Adaptive Filter Performance, International Conference on Telecommunications, ITC2000, May 2225, 2000, Acapulco, Mexico, pp.195-200 ; 60. Zoican Sorin, Zoican Roxana, - Enhanced Voice Activity Detector Algorithm for Wireless Communication, International Conference Communication2000, Military Technical Academy, december 2000, Bucharest; 61. Wakerly John F., - Digital Design, Pretice Hall, New Jersey, 2000; 62. *** - TMS320C24x DSP Controllers - Reference Set: Vol.1, Texas Instruments Inc, 1997; 63. *** - TMS320C24x DSP Controllers - Reference Set: Vol.2, Texas Instruments Inc, 1997; 64. *** - PIC 16F87x Users Manual, Microchip, 2002. 156

You might also like