INIŢIERE – Lecţia 6 (continuare din numărul trecut)

10 MAI 2001

Remarcaţi că toate liniile se dezvoltă pe verticală – pentru a putea fi citite cu uşurinţă, iar o altă regulă folosită de asamblor indică faptul că trebuie lăsat cel puţin un spaţiu liber între fiecare câmp al liniei. De asemenea se preferă nume scurte pentru etichete (8 caractere), rămânând spaţiu suficiet pentru scrierea comentariilor. Comentariile sunt foarte importante. Când scrieţi un program pentru prima dată, tendinţa este să nu acordaţi prea multă importanţă comentariilor pentru că vă grăbiţi. Dar dacă reveniţi la acest program câteva săptămâni mai târziu, vă este mult mai uşor să înţelegeţi ce aţi scris în program dacă aţi acordat timp suficient scrierii unor comentarii clare şi riguroase. De asemenea, comentariile vă ajută la depanarea programului.
În exemplul precedent am rezervat doi octeţi în memorie şi am stocat valoarea 2 în fiecare. Apoi conţinutul primului octet – first – l-am mutat în acumulator şi apoi am adunat conţinutul octetului secnd cu conţinutul acumulatorului. Deci în acumulator este memorată în final valoarea 4, iar first şi secnd rămân neschimbaţi. Această metodă are avantajul că nu trebuie să vă faceţi griji care octet este first sau care este secnd, această sarcină fiind preluată de acumulator. Diferenţa dintre directivele .rs şi .equ este aceea că prin directiva .equ se spune asamblorului exact ce bit vrei să denumeşti pe când cu directiva .rs ordinea în care am rezervat octeţii determină care este first şi care este secnd. Nu contează foarte mult acest lucru deoarece sunt referiţi după nume şi nu după locaţia actuală. În DS5000 sunt mai multe metode de adresare a variabilelor.
Una din ele este adresarea regiştrilor r0, r1, r2, etc.
O altă metodă este adresarea directă. Aceasta utilizează adresa actuală din memoria RAM internă unde este plasată variabila. Adresarea directă se poate face folosind un nume cu directiva .rs. Asamblorul atribuie adresa actuală variabilei denumite în ordinea în care este scrisă în directivele .rs. Dacă variabila first a avut locaţia actuală 0, atunci variabila secnd va avea locaţia 1. Locaţia sau adresa reprezintă acelaşi lucru. Când programul este asamblat, numele sunt omise şi sunt folosite adresele.
Altă formă de adresare este adresarea imediată.
Această formă a fost utilizată în programul în care am adunat numerele 2 şi 2. Aceasta este indicată prin simbolul # pus în faţa numărului respectiv. Acesta indică asamblorului că numărul este un operand asupra căruia acţionează instrucţiunea. De asemenea, metoda a fost folosită în exemplul anterior când variabilelor secnd şi first li s-a atribuit valoarea 2. Pentru a aduna cele două numere s-a utilizat adresarea directă.
Iată aceste instrucţiuni şi ce tip de adresare se foloseşte pentru fiecare.
first: .rs 1 ; directivă
secnd: .rs 1 ; directivă
mov first,#2 ;adresare directă, imediată
mov secnd, #2 ;adresare directă, imediată
mov a,first ;adresare implicită, directă
add a,secnd ;adresare implicită, directă
Programul original de adunare 2+2 şi modurile de adresare ale fiecărei instrucţiuni sunt prezentate mai jos:
mov r0,#3 ;regiştri, adresare imediată
mov a,#2 ;regiştri, adresare imediată
add a,r0 ;adresare implicită, regiştri
Fiecare instrucţiune poate avea două moduri diferite de adresare, unul pentru destinaţie şi unul pentru sursă. De asemenea, acumulatorul A se adresează implicit, iar adresare registru se referă strict la regiştrii r0, r1, r2, etc., chiar dacă anterior ne-am referit la acumulator ca la un registru. În DS5000 acumulatorul face parte din regiştrii cu funcţii speciale, dar instrucţiunea indică faptul că acumulatorul va fi utilizat ca sursă sau destinaţie. Adresarea implicită este o metodă de adresare care scurtează numărul de octeţi ai instrucţiunilor particulare asamblate în aceştia.
Pentru a puncta acest lucru să ne abatem puţin de la subiect. O instrucţiune de tipul add a,r0 este o instrucţiune pe un octet. Cu alte cuvinte această instrucţiune va ajunge în DS5000 sub forma unui singur octet. O parte din acest byte este codul operaţiei, iar cealaltă parte reprezintă registrul utilizat. Întrebarea care apare este “Cum pot octeţii unui program asamblat să-şi ocupe locul în interiorul mC?
Ideea este să ocupi cât mai puţin spaţiu cu putinţă. De aceea este utilizată adresare implicită. Aceasta limitează posibilităţile de alegere în utilizarea unei instrucţiuni; întotdeauna se utilizează acumulatorul ca sursă sau ca destinaţie micşorându-se astfel mărimea instrucţiunii, deci se pot implementa programe cât mai complexe. Aceasta este alegera făcută de producătorii mC. Este o renunţare la flexibilitate în favoarea dimensiunii. De aceea veţi vedea o mulţime de instrucţiuni care utilizează acumulatorul.
În cazul unei instrucţiuni de tipul add a,secnd sunt asamblaţi doi octeţi. Primul octet indică faptul că aceasta este o instrucţiune de tip add şi acumulatorul este adresat implicit ca destinaţie. Iar al doilea octet este adresarea directă a variabilei sursă, secnd. Acest lucru este transparent pentru programator deoarece se foloseşte un asamblor, dar rezultatele invizibile merită să fie cunoscute când se încearcă să se implementeze programe cât mai complexe.
O altă formă de adresare a variabilelor se numeşte adresare indirectă simplă sau adresarea indirectă a regiştrilor. Aceasta este puţin mai complicată. Aici adresa este memorată într-un registru, altul decât r0 sau r1. În următorul program se va exemplifica metoda de adresare indirectă a registrilor. Presupunem că trebuie adunate două numere: 2+2. (prob05.asm)
buffer: .rs 2 ;rezervă două locaţii pentru date
mov r0,#buffer ;setează r0 la începutul bufferului
mov @r0,#2 ;pune valoarea 2 în prima locaţie din buffer
inc r0 ;incrementează r0
mov @r0,#2 ;pune valoarea 2 în a doua locaţie din buffer
mov r0,#buffer ;setează r0 la începutul bufferului
mov a,@r0 ;pune în acumulator valoarea din locaţia r0
inc r0 ;incrementează r0
add a,@r0 ;adună conţinutul celei de-a doua locaţii din buffer cu conţinutul A
Linia 1 este o directivă de rezervare a unui spaţiu de memorie, dar de data aceasta se rezervă două locaţii, câte una pentru fiecare valoare. Linia 2 setează r0 în prima locaţie de memorie a bufferului creat prin directiva .rs. Cum am declarat anterior, # înseamnă adresare imediată, dar asamblorul vede că primul caracter după # nu este un număr, deci caută eticheta buffer şi obţine adresa directă unde este situat în memoria internă şi pune acea adresă în r0. Puţin cam încurcate dar aşa se petrec lucrurile în această linie.
Linia 3 memorează valoarea 2 în prima locaţie a bufferului. Simbolul @ indică asamblorului că următorul registru memorează adresa (indirect) în care este stocată valoarea 2. Deci după această instrucţiune primul octet al bufferului conţine valoarea 2. Linia 4 incrementează r0 la următoarea locaţie a bufferului. Linia 5 este similară liniei 3 exceptând faptul că valoarea 2 este memorată în al doilea byte al bufferului. Linia 6 este identică cu linia 2, aduce r0 în prima locaţie a bufferului. Linia 7 mută conţinutul primului byte din buffer (primul 2) în acumulator. Linia 8 incrementează r0 la adresa următorului 2 din buffer. Linia 9 adună cele două numere şi memorează rezultatul în acumulator. Iată modurile de adresare ale fiecărei linii:
buffer: .rs 2 ;directivă
mov r0,#buffer ;regiştri, adresare imediată
mov @r0,#2 ;adresare indirectă, imediată
inc r0 ;operaţie aritmetică, se adună 1 cu r0
mov @r0,#2 ;adresare indirectă, imediată
mov r0,#buffer ;regiştri, adresare imediată
mov a,@r0 ;adresare implicită, indirectă
inc r0 ;operaţie aritmetică, se adună 1 cu r0
add a,@r0 ;adresare implicită, indirectă
Iată un alt exemplu de adunare 2+2, dar cu o altă metodă.(prob06.asm)
buffer .rs 2 ;rezervă 2 bytes pentru date
mov #buffer,#2 ;pune 2 în prima locaţie din buffer
mov #buffer+1,#2 ;pune 2 în a doua locaţie din buffer
mov a,buffer ;mută conţinutul primei locaţii din buffer în acumulator
add a,buffer+1 ;adună 2+2
Linia 1 rezervă 2 octeţi în memorie. Linia 2 pune valoarea 2 în prima locaţie a bufferului, iar linia 3 pune valoarea 2 în a doua locaţie a bufferului. Linia 4 mută primul 2 în acumulator. Linia 5 adună conţinutul acumulatorului (primul 2) cu conţinutul celei de-a doua locaţii a bufferului, iar rezultatul îl memorează în acumulator.
Mai sunt multe alte metode de rezolvare a acestei probleme. Dacă o problemă este dată spre rezolvare la 100 de programatori, probabil se vor obţine 100 de programe diferite care
ajung la acelaşi rezultat.
Un program scris în limbaj de asamblare trebuie convertit în cod maşină, conversia făcându-se unu la unu adică fiecare linie scrisă în program se transformă într-o instrucţiune în binar; de fapt, această conversie se numeşte asamblare.
Fişierul scris în limbajul de asamblare este denumit program sursă, iar cel rezultat în urma asamblării este denumit fişier obiect.
Fişierul obiect este fişierul ce va fi încărcat în DS5000. Sunt deci două fişiere diferite. Unul este cel scris în editorul de texte (fişierul sursă), iar celălalt este creat de asamblor (fişierul obiect).
Sunt câteva directive ce se folosesc în programarea mC pe care nu le-am abordat. Una din acestea este directiva .org – directiva origine. Aceasta indică asamblorului adresa din DS5000 în care va fi plasat primul octet al codului asamblat. Aceasta este originea sau începutul programului. De exemplu.
.org h’0000
mov r0,#buffer ;setează r0 la începutul bufferului
mov @r0, #2 ;pune 2 în prima locaţie a bufferului
inc r0 ;incrementează r0
mov @r0, #2 ;pune 2 în a doua locaţie a bufferului
mov r0,#buffer ;setează r0 la începutul bufferului
mov a,@r0 ;mută conţinutul primei locaţii de memorie în acumulator
inc r0 ;incrementează r0
add a,@r0 ;adună 2+2
.segment .memory
.memory
.org h’00
buffer: .rs 2

Prima parte este identică cu prob05.asm cu excepţia directivei .org. Aceasta spune asamblorului că primul byte al codului va fi asamblat la adresa 0000h. Directiva .segment utilizată la sfârşitul programului indică faptul că se va utiliza o zonă de memorie internă denumită .memory. Următoarea linie conţine o directivă .memory care permite accesul la memoria internă RAM. Următoarea directivă .org indică faptul că zona de memorie rezervată are adresa 00h. Deci adresa bufferului este 00h sau 0. Aceasta este valoarea adresei încărcată în registrul r0 atunci când se efectuează instrucţiunea mov r0,#buffer.
Am parcurs un volum mare de informaţii în această lecţie. În lecţia următoare vom încerca să asamblăm aceste programe şi le vom rula în simulator.
n
– va urma –
Ioana Enache
NOTĂ
Toate fişierele: prob01.asm, prob02.asm, prob03.asm, prob04.asm prob05.asm, prob06.asm- le găsiţi în pagina WEB a ziarului:
www.electronica-azi.ro e-mail: office@electronica-azi.ro)

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile necesare sunt marcate *

  • Folosim datele dumneavoastră cu caracter personal NUMAI pentru a răspunde comentariilor/solicitărilor dumneavoastră.
  • Pentru a primi raspunsuri adecvate solicitărilor dumneavoastră, este posibil să transferăm adresa de email și numele dumneavoastră către autorul articolului.
  • Pentru mai multe informații privind politica noastră de confidențialitate și de prelucrare a datelor cu caracter personal, accesați link-ul Politica de prelucrare a datelor (GDPR) si Cookie-uri.
  • Dacă aveți întrebări sau nelămuriri cu privire la modul în care noi prelucrăm datele dumneavoastră cu caracter personal, puteți contacta responsabilul nostru cu protecția datelor la adresa de email: gdpr@esp2000.ro
  • Abonați-vă la newsletter-ul revistei noastre