Documente Academic
Documente Profesional
Documente Cultură
Raport
La lucrarea de laborator № 3
Disciplina: Microprocesoare
Tema: „Subrutine”
Gurduza Petru
Lazari Eugeniu
Chișinău 2016
Partea teoretica:
Stiva (Stack).
Stiva este un mecanism care permite stocarea temporara a datelor dupa principiul LIFO (Last Input First Output) -
Primul Intrat Ultimul Iesit.
Introducerea in stiva se va executa prin comanda PUSH R - introducerea continutului unui Registru de Uz
General in Stiva (R -> STACK). Extragerea datelor cu comanda POP R (R <- STACK).
Deasemenea stiva este un mecanism fara de care nu este posibil lucrul cu subrutinele, deoarece mecanismul
stivei permite stocarea temporara a Contorului de Program PC pe durata executiei subrutinei. Respectiv
comenzile de tip CALL si RET deasemenea vor introduce/extrage date din stiva.
Mecanismul de stiva este realizat in baza memoriei RAM si un Registru Indicator de Stiva - SP (Stack Pointer).
Indicatorul de stiva SP indica la adresa curenta de scriere in spatiul RAM.
SP este un registru dublu (16 biti), construit in baza [ SPH : SPL ] facilitand accesul la intreg spatiul de memorie,
pana la 64 K.
Executand comanda PUSH R continutul registrului se va inregistra la adresa ce se contine in registrul Indicator
de Stiva SP, dupa care are loc decrementarea SP.
PUSH R
1. RAM[SP] = R
2. SP = SP - 1
Pentru comanda POP R executia presupune Incrementarea Indicatorului de stiva SP urmata de transferul in
Registrul de Uz General a valorii de la adresa SP
POP R
1. SP = SP + 1
2. R = RAM[SP]
Adaugarea elementelor in stiva va implica cresterea stivei. reesind din cele spuse mai sus, vom afirma ca Stiva
creste in directia diminuarii adreseilor memoriei RAM.21
Initializarea Stivei
Registrul Indicator de Stiva SP este localizat in spatiul registrilor periferici, respectiv citirea si modificarea valorii
din SP se va efectua prin comenzile IN si OUT.
Deoarece valoarea indicatorului de stiva SP descreste odata cu cresterea stivei, se recomanda initializarea stivei
la o adresa avansata in spatiul de memorie RAM. O asemenea valoare pote fi constanta RAMEND care contina
ultima adresa existenta din memoria RAM interna a Microcontrollerului.
Operatia de Initializare a stivei va consta in initializarea Indicatorului de stiva SP.
SP = RAMEND, [SPH:SPL] = RAMEND
Secventa de cod in ASM pentru operatia de mai sus va arata in felul urmator:
ldi R16, LOW(RAMEND)
out SPL, R16 ; initializare byte inferior SP
ldi R16, HIGH(RAMEND)
out SPH, R16 ; initializare byte superior SP
unde:
LOW - macroinstructiunea pentru selectarea byte-ului inferior dintr-o constanta.
HIGH - macroinstructiunea pentru selectarea byte-ului superior dintr-o constanta.
Intr-un ciclu de program numarul de inregistrari trebuie sa fie egal cu numarul de extrageri pentru a evita erori
de scurgere sau violare de memorie.
Subrutina
Subrutina - Secventa de instructiuni grupata intre o eticheta (label) si instructiune de returnare din subrutina RET.
Eticheta reprezinta o adresa in memoria de programe fiindui atribuit un nume de acces. In program va fi
reprezentata de un nume de eticheta urmata de (:)
MySub: ; Numele subrutinei reprezentata de
; eticheta inceputui subrutinei
...
... ; Corpul subrutinei
...
ret ; returnare din subrutina
Subrutina poate fi apelata prin numele ei cu una din comanzile de chemare subrutinei CALL, RCALL sau ICALL.
...
rcall MySub ; apelul subrutinei MySub
...
Mecanismul de chemare a subrutinei consta in salvarea adresei curente de executie in stiva pentru a avea
posibilitatea de a restabili executia comenzilor urmatoare dupa returnarea din subrutina.
Instructiunea de apel a subrutinei cu o instructiune de tip CALL ca fi interpretata dupa cum urmeaza:
Odata cu chemarea subrutinei are loc salvarea in stiva a contorului de program si restabilirea lui la returnarea din
subrutina.
1. PC -> STACK - salvarea adresei curente in Stiva
2. jmp MySub - salt la adresa etichetei My Sub
Returnarea din subrutina are loc odata cu executarea comenzii RET ca regula plasata la sfirsitul subrutinei.
Pentru returnare din subrutina vom avea:
1. PC <- STACK - restabilirea adresei din stiva
2. PC <- PC + 1 - trecerea la comanda urmatoare dupa comanda de apel a subrutinei
De mentionat ca Contorul de Program PC este un registru de 16 biti, respectiv va a ocupa doua locatii in stiva,
executanduse doua operatii de salvare a unui byte in stiva.
Deoarece un apel de subrutina presupune utilizarea stivei. este strict recomandat ca inainte de un oarecare
prim apel stiva sa fie initializata, iar locul cel mai potrivit este in partea de initializare a programului.
De mentionat ca ordinea restabilirii registrilor de lucru este inversa celei de salvare, conform principiului LIFO al
stivei.
Subrutina cu parametri
In calitate de parametri al unei subrutine pot fi utilizati registrii de uz general. In asa mod pentru a transmite
date date de intrare in subrutina, inainte de a apela o subrutina este nevoie ca registrii utilizati ca parametri sa fie
initializati cu valorile de intrare dorite pentru acesti parametri. Iar dupa executia subrutinei se vor prelua valorile
din registrii rezervati parametrulilor de iesire.
Apelul de subrutina va arata in felul urmator:
...
ldi r16, K1 ; initializarea primului paramatru
ldi r17, K1 ; initializarea parametrului al doilea
rcall MySub ; apelul subrutinei MySub
sts a, r18 ; preluarea rezultatului subrutinei
...
Registrii utilizati ca parametri de intrare/iesire NU vor fi salvati in interiorul subrutinei. Mecanismul de salvare a
registrilor utilizati ca parametri in scop de masura de protectie a datelor curente din acesti registri se va
implementa dupa cum urmeaza: paramtrii se vor salva in stiva inainte de initializare si se vor restabili dupa
preluarea rezultatului subrutinei.
...
push r16 ; salvarea registrului parametru r16
push r17 ; salvarea registrului parametru r17
push r18 ; salvarea registrului parametru r18
ldi r16, K1 ; initializarea primului paramatru
ldi r17, K1 ; initializarea parametrului al doilea
rcall MySub ; apelul subrutinei MySub
sts a, r18 ; preluarea rezultatului subrutinei
pop r18 ; restabilirea registrului parametru r16
pop r17 ; restabilirea registrului parametru r17
pop r16 ; restabilirea registrului parametru r18
...
Partea practica:
Obiectivele lucrarii:
1) Utilizarea subrutinelor cu parametru in limbajul Assembler.
Scopul lucrarii:
1) Sa se realizeze un program cu ajutorul AVR Studio care ar seta doua porturi la intrarea semnalului, iar celelalte
doua la iesire. La porturile de intrare sa fie setate doua numere, care apoi sa se faca operatia de imultire.
Rezultatele se fie repartizare pe 16 biti si sa fie aratate pe indicatori de 7 segmente.
Mersul lucrarii:
1. Cream in proiect nou in AtmelStudio:
2. Elaboram solutia problemei formind shema-bloc. Conform algoritmului obtinut scriem
listingul in assembler.
Schema-bloc:
3. Listingul programului:
main:
init: ;Incepem initializarea
LDI R16,0x00 ;Incarcam o constanta intr-un RUG
LDI R17,0xFF
OUT DDRA,R16 ;Initializam portul A ca port de intrare si acrivam rezistenta de
pull-up
OUT PORTA,R17
OUT DDRB,R16 ;Initializam portul B ca port de intrare si acrivam rezistenta de
pull-up
OUT PORTB,R17
OUT DDRC, R17 ;Initializam portul C ca port de iesire
OUT PORTC,R16
OUT DDRD,R17 ;Initializam portul D ca port de iesire
OUT PORTD,R16
endinit: ;Sfirsitul initializarii
stackinit: ;Initializarea stivei
LDI R17,LOW(RAMEND)
OUT SPL,R17
LDI R17,HIGH(RAMEND)
OUT SPH,R17
endstackinit: ;Sfirsitul initializarii stivei
IN R18,PINA ;Incarcam val. din port in reg. pentru a putea lucra in continuare cu
valorile acestora
IN R19,PINB ;AH:AL(R18:R19)
;RH:RL(R20:R21)
CALL MYMUL ;Apelul subrutinei pt inmultire
RJMP main_loop
endmain_loop:
ret
L2: SBRS R19,0 ;Verificam daca bitul din registru este setat
RJMP L4 ;Daca nu sare la L4, daca da merge in continuare la L3
L3: ADD R21, R18 ;Adunam aritmetic fara transport, valorile de low AL:RL
ADC R20, R22 ;Adunam cu transport, valorile de high AH:RH
RJMP L1
POP R22
5. Cream schema electrica a circuitului in Proteus verificind daca avem erori logice.
Schema electrica:
6. Concluzii:
In urma efectuarii lucrarii de laborator am studiat si am utilizat subrutinele.Am realizeazat
inmultirea a doua numere. Am inteles cum se poate de lucrat cu subrutinele, apoi am afisat
rezultatele pe indicatoare de 7 segmente. Am utilizat subrutinele securizate si am observat ca ele
ne permit sa nu afectam starea globala a controlerului (valorile registrilor utilizati dupa executia
subrutinei ramin aceleasi).