Limbajul de asamblare
Limbajul de asamblare permite înţelegerea la nivel de amănunt a ceea ce se întâmplă într-un mC. În DS500 instrucţiunile sunt stocate în format hexa şi privite în ansamblu sunt foarte greu de descifrat. Un asamblor este un program care permite scrierea instrucţiunilor, într-o formă mai mult sau mai puţin literară, dar care este mult mai uşor de descifrat şi în urma operaţiei de asamblare acestea sunt convertite sau asamblate în numere hexa. Codul se scrie cu ajutorul unui editor de texte, se salvează şi apoi se asamblează cu ajutorul asamblorului. Rezultatul este un fişier nume.asm ce trebuie încărcat în DS5000.
Iată un exemplu: adunarea a două numere (2+2). (Numiţi fişierul: prob01.asm – îl găsiţi în pagina WEB a ziarului – www.electronica-azi.ro sau pe e-mail: office@electronica-azi.ro).
mov r0,#2
mov a#2
add a,r0
Prima linie: pune valoarea 2 în registrul r0. A doua linie: încarcă acumulatorul cu 2. Acestea sunt datele necesare programului. A treia linie adună la acumulator conţinutul registrului r0 şi rezultatul îl pune în acumulator, vechea valoare din acumulator fiind ştearsă. Acumulatorul conţine acum 4, iar valoarea din registrul r0 rămâne neschimabtă: 2.
Limbajul de asamblare respectă anumite reguli ce vor fi descrise pe măsură ce vor fi utilizate. Sintaxa este aceeaşi pentru majoritatea instrucţiunilor: se scrie numele instrucţiunii urmat de un spaţiu liber apoi destinaţia, virgulă, sursa.
instrucţiune destinaţie,sursă
Operanzii destinaţie şi sursă reprezintă datele asupra cărora acţionează instrucţiunea. Aceştia pot fi: un registru, un cuvânt dată, o adresă.
În continuare vom citi un comutator, iar dacă comutatorul este apăsat vom comanda un LED. Bitul 0 al portului p1 va fi comutatorul. Când comutatorul este în poziţia închis bitul zero va fi 1, iar dacă comutatorul este în poziţia deschis, bitul zero va fi 0. Considerăm LED-ul ca fiind bitul 0 al portului p0. Dacă bitul zero este 0, atunci LED-ul este stins, iar dacă bitul 0 este 1 atunci LED-ul este aprins. Toţi ceilalţi biţi ai porturilor p0 şi p1 vor fi ignoraţi şi presupunem că au valoarea 0. (Acesta este fişierul prob02.asm).
start: mov a,p1 ;încarcă în acumulator valoarea din bitul 0 al portului p1
mov p0,a ; mută conţinutul acumulatorului în bitul 0 al portului p0
sjmp, start; salt la linia care are eticheta start
Prima linie conţine un element de noutate. Se numeşte etichetă (label) şi în acest caz aceasta este start:. O etichetă este o metodă prin care se transmite asamblorului că această linie are un nume şi adresată ulterior se poate reveni la efectuarea instrucţiunii de pe această linie. Toate etichetele sunt urmate de simbolul “:” acesta defineşte de fapt o etichetă. Un câmp foarte important al unei linii îl constituie comentariul. Un comentariu începe întotdeauna cu simbolul “;” care spune asamblorului să ignore tot ce urmează după acest simbol deoarece este un comentariu. Comentariile sunt foarte utile programatorului dacă se revine asupra programului scris după o anumită perioadă de timp. În prima linie se citeşte comutatorul prin citirea portului p1 (sursa) şi pune valoarea citită în acumulator (destinaţia).
Următoarea linie scrie valoarea din acumulator (sursa) în portul p0, care are LED-ul ataşat (destinaţia). Următoarea linie efectuează un salt la linia care are eticheta start. Aceasta completează bucla prin care se citeşte starea comutatorului şi se scrie la LED.
Dacă comutatorul este închis din prima linie rezultă ca valoarea din acumulator este 1, iar din a doua linie se pune în p0 1 deci LED-ul va fi aprins. Dacă comutatorul este deschis conform primei linii se pune 0 în acumulator, din a doua linie se va pune 0 în portul p0 deci LED-ul va fi stins. Această buclă va continua la nesfârşit citind întrerupătorul şi scriind în LED până când mC este închis sau până va fi încărcat un nou program. Dacă comutatorul este în poziţia închis, LED-ul va rămăne aprins în continuare.
Această problemă poate fi rezolvată foarte simplu dacă se conectează un conector direct la un LED, aşa cum sunt conectate becurile acasă. Cu un mC se pot realiza mult mai multe lucruri. Putem aprinde sau stinge un LED cu ajutorul unui timer în funcţie de timp. Sau putem monitoriza temperatura şi putem aprinde sau stinge LED-ul în funcţie de temperatura acestuia. Putem de asemenea monitoriza mai multe comutatoare şi putem aprinde sau stinge LED-ul pe baza unei combinaţii de comutatoare.
În exemplul anterior am presupus că ceilalţi biţi ai porturilor p0 şi p1 au valoarea 0. Dar în realitate fiecare bit poate avea atribuită o anumită funcţie. În program trebuie luat în consideraţie numai bitul 0 din portul p0 şi bitul 0 din portul p1. Acest lucru complică problema.
În asamblare se poate atribui un nume unui bit şi acesta va fi adresat prin acest nume. Acest lucru se poate realiza cu o directivă de egalitate. Directivele sunt comenzi speciale ale asamblorului menite doar pentru facilitarea scrierii programului şi pentru a determina anumite operaţii în procesul de asamblare. Toate directivele încep cu un punct “.”.
În DS5000 sunt multe locaţii de un bit. 128 din acestea au fost prezentate în lecţia anterioară. Sunt şi altele cum ar fi biţii din acumulator, biţii din porturile p0, p1, p2, p3. Fiecăreia îi este atribuită o adresă de către DS5000 şi aceasta nu poate fi schimbată Primele 128 de locaţii sunt cei 16B de memorie internă RAM urmaţi de 32B. Bitul 0 din p0 este adresat prin 128 (80h) şi bitul 0 din p1 este adresat prin 144 (90h).
Cum se transpune acest lucru în asamblare?. (prob03.asm)
.equ switch,144 ; bitul 0 din portul p1 este denumit switch
.equ led,128 ; bitul 0 din portul p0 este denumit LED
start: mov c,switch ; determină starea comutatorului şi pune valoarea în flagul carry
mov led,c ; pune valoarea din flagul c în LED
sjmp start ; salt la linia start
Prin acest program se obţine acelaşi rezultat ca programul anterior, dar nu se mai presupune nimic în legătură cu ceilalţi biţi ai porturilor p0 şi p1. Directivele de egalitate sunt iniţializate o dată la începutul programului şi apoi numele sau etichetele sunt utilizate în loc de numărul bitului. Acest lucru simplifică munca programatorului. Toţi biţii mutaţi trebuie să ajungă în flagul c. Toate egalităţile trebuie definite înainte de a fi utilizate în program. Acelaşi lucru este valabil şi pentru etichete. Un alt avantaj al denumirii biţilor printr-o directivă de egalitate flexibilitatea programului şi anume, dacă în procesul de proiectare se decide folosirea altui bit pentru LED sau pentru comutator, se schimbă numai linia cu directiva de egalitate nu tot programul.
O altă metodă de a aduna 2 numere foloseşte o tehnică similară şi anume rezervarea unui spaţiu în memorie, utilizându-se directiva .rs (reserve storage). Exemplul următor ilustrează cum arată un program în acest caz (prob04.asm)
first: .rs 1 ; rezervă un octet denumit
first
secnd: .rs 1 ; rezervă un octet denumit
secnd
mov first,#2 ; pune valoarea 2 în first
mov secnd,#2 ; pune valoarea 2 în secnd
mov a,first ; mută conţinutul lui first în ascumulator
add a,secnd ; adună conţinutul lui secnd cu valoarea din acumulator
Prima linie ilustrează directiva .rs – primul câmp reprezintă numele sau eticheta, al doilea este directiva şi al treilea reprezintă cantitatea de memorie alocată. În acest caz s-a rezervat un singur octet pentru fiecare variabilă.
-va urma-
NOTĂ
Toate fişierele: prob01.asm, prob02.asm, prob03.asm, prob04.asm – le găsiţi în pagina WEB a ziarului:
www.electronica-azi.ro e-mail: office@electronica-azi.ro
Dar dacă ne referim la un 8051, memoria externă va fi conectată prin porturile p0 şi p2.
Jumătate din pinii portului p3 vor fi folosiţi pentru funcţiile lor speciale, iar ceilalţi 4 vor fi intrări/ieşiri obişnuite.
Doi pini din portul p3 sunt folosiţi pentru comunicaţia serială cu DS5000. Prin intermediul acestor pini, datele vor fi transmise serial între un PC şi DS5000. În acest mod se va încărca dintr-un calculator programul scris pentru DS5000.
Alţi doi pini sunt alocaţi întreruperilor.
În programul din lecţia 1, în care descriam paşii necesari traversării unei intersecţii, dacă o persoană din apropiere întrebă cât este ceasul acesta ar fi un exemplu de întrerupere. Această întrerupere nu modifică structura programului, ci doar îl opreşte o perioadă de timp din funcţionare, timp în care se poate răspunde la întrebare. După aceea se continuă execuţia următoarului pas din program.
Întreruperile au asociat un program care poate indica mC modul de tratare al acestora. În cazul nostru, “programul asociat” va privi ceasul şi va răspunde la întrebare.
Aceasta se numeşte o rutină de întrerupere. De fiecare dată când apare o întrerupere, programul principal este oprit temporar, este executată rutina de întrerupere şi apoi se revine la programul principal.
În următoarele lecţii vom aloca timp suficient pentru a descrie întreruperile şi mai ales modul de utilizare al acestora.
DS5000 conţine 128B de memorie RAM internă.
Primii 32B sunt alocaţi pentru 4 grupuri de regiştri denumiţi b0, b1, b2, b3. Dacă se alimentează mC pentru prima oară, grupul de regiştri b0 este activ, pentru activarea celorlate grupuri de regiştri există o anumită comandă care permite comutarea acestora. Fiecare grup este format din 8 regiştri diferiţi denumiţi r0, … r7, folosiţi pentru stocarea temporară a instrucţiunilor sau a datelor din program. Există ca în orice mP un registru acumulator. Acesta este folosit pentru stocarea temporară a rezultatelor diferitelor instrucţiuni cum ar fi adunare, scădere etc.
Următorii 16B din memoria RAM sunt folosiţi pentru stocarea şi restabilirea biţilor. Noile generaţii de mC realizate nu au această facilitate, de altfel foarte necesară.
Ultimii 80B din RAM sunt pentru stocarea informaţiilor în general şi sunt folosiţi pentru diferite lucruri.
Mai există încă 128B de memorie în care se regăsesc regiştri cu funcţii speciale.
În acest domeniu se regăsesc acumulatorul şi numărătorul de programe împreună cu alţi regiştri care controlează diferite aspecte ale funcţionări mC DS5000.
În DS5000 mai există încă un domeniu de memorie, divizat în două părţi, memoria de programe şi memoria de date. În realitate există un bloc de 32K de memorie RAM care prin programarea unora din regiştri cu funcţii speciale poate fi împărţit în cele două secţiuni. În majoritatea aplicaţiilor următoare acesta va fi modul de lucru, vom împărţi acest bloc în 16KB memorie de programe şi 16KB memorie de date.
Memoria de programe este protejată la scriere, deci un program “rătăcitor” nu se poate modifica singur în mod accidental. Memoria de date poate fi scrisă sau citită prin intermediul programului.
DS5000 conţine o baterie de Li care permite menţinerea programelor şi a datelor în memorie chiar dacă acesta nu mai este alimentat. Aceasta este una din cele mai importante facilităţi oferite de DS5000 şi nu cred că mai există un alt mC care oferă această facilitate. În majoritatea mC există memorie PROM sau EPROM pentru memoria de programe.
Memoria PROM poate fi scrisă o dată şi programul implemenat este definitiv. Memoria EPROM poate fi scrisă şi apoi ştearsă cu ajutorul unui fascicol de radiaţii UV prin intermediul ferestrei prevăzute în mC. Dar acest lucru necesită un programator special şi o sursă de radiaţii UV (aprox. 125$).
În DS5000 există doi pini care pot fi poziţionaţi special pentru a încărca un program dintr-un calculator în chip prin interfaţa serială. Un program special cu care este prevăzut DS5000 permite acest lucru; acesta este dezactivat când cei doi pini sunt readuşi în poziţia normală.
Pentru a încărca un program în mC se accesează acest program special, se încarcă programul şi apoi se comută pinii în poziţia normală.
Elegant nu?
Acest lucru durează doar câteva secunde comparativ cu o jumătate de oră cât durează ştergerea unui program dintr-un mC bazat pe memorii EPROM. În plus, nu este necesar decât un port serial.
Această facilitate accelerează dezvoltarea programului şi permite modificarea acestuia, încărcarea în chip şi execuţia lui în aproximativ 1 minut.
Timpul necesar dezvoltării şi depanării programului este mult mai mare decât timpul necesar împlementării acestuia în mC.
Pentru a putea testa programele elaborate fără a fi nevoie să le încărcaţi în DS5000, ar fi necesar un simulator 8051. Puteţi vizualiza astfel toate modificările regiştrilor pe măsură ce programul parcurge fiecare instrucţiune.
Aceasta este o metodă care accelerează procesul de depanare a programului fiind şi o metodă didactică care permite vizualizarea modului în care fiecare instrucţiune influenţează diferitele componente ale mC DS5000.
Vom utiliza această metodă în lecţiile viitoare pentru a ilustra diferitele instrucţiuni sau programe pe care le vom scrie.
În următoarea lecţie vom începe cu limbajul de asamblare, metoda pe care o vom folosi pentru a scrie programele.
• Ioana Enache