Sunteți pe pagina 1din 7

Universitatea Tehnică a Moldovei

Facultatea Calculatoare, Informatică şi Microelectronica

Catedra Microlectronica şi Ingineria Biomedicala

Raport
La lucrarea de laborator № 3

Disciplina: Microprocesoare

Tema: „Subrutine”

A efectuat: studentul grupei MN-141

Gurduza Petru

A verificat: lector asistent

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.

.include "m32def.inc" ; includem fisierul de adrese la periferice


                      ; pentru Atmega32
.cseg                 ; indicam inceputul segmentului de cod
.org 0                ; programul va fi inregistrat de la 
                      ; adresa 0x00
init:                 ; punctul de intrare in program
    ldi R16, LOW(RAMEND) ; initializarea stivei
    out SPL, R16
    ldi R16, HIGH(RAMEND)
    out SPH, R16
    ...
Subrutina securizata.
Vom numi subrutina securizata subrutina care nu afecteaza valorile registrilor prin executia sa. Mecanismul
subrutinei securizate consta in salvarea registrilor de lucru, utilizati in subrutina in stiva la inceputul subrutinei si
restabilirea valorilor registrilor inainte de returnare din subrutina.
MySub:          ; Numele subrutinei reprezentata de  
                ; eticheta inceputui subrutinei
    push r15    ; salvarea registrului r15
    push r16    ; salvarea registrului r16
    ...         ; Corpul subrutinei
    ...         ; utilizare registri r15 si r16
    ...
    pop r16     ; restabilire r16
    pop r15     ; restabilier r16
    ret         ; returnare din subrutina

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:

Fig.1 Schema bloc

3. Listingul programului:

.include "m32def.inc" ;Includem fisierul de descrierea a controlerului


.cseg ;Anuntam segmentul de cod
.org 0 ;Stabilim adresa curenta la pozitia 0

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

main_loop: ;Inceperea procesarii

PUSH R18 ;Securizam registrii


PUSH R19
PUSH R20
PUSH R21

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

OUT PORTC, R20 ;AH ;Afisarea rezultatului pt inmultire


OUT PORTD, R21 ;AL

POP R21 ;Restabilim registrii


POP R20
POP R19
POP R18

RJMP main_loop
endmain_loop:
ret

MYMUL: ;Eticheta subrutinei de inmultire


PUSH R22
CLR R20 ;Curatim rezultatul high
CLR R21 ;Curatim rezultatul low

L0: CPI R18,0 ;Verificam daca valoarea PINA = 0


BREQ MYMUL_END ;Daca da,sare la sfirsitul subrutinei
L1: CPI R19,0 ;Daca nu,verificam daca valoarea PINB = 0
BREQ MYMUL_END ;Daca da, sare la sfirsitul subrutinei

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

L4: LSL R18 ;Shiftare logica la stinga


ROL R22 ;Rotare la stinga peste bitul de transport
LSR R19 ;Shiftare logica la dreapta

RJMP L1
POP R22

MYMUL_END: ;Sfirsitul subrutinei de inmultire


RET
4. Controlam de erori sintaxice codul obtinut:

5. Cream schema electrica a circuitului in Proteus verificind daca avem erori logice.
Schema electrica:

Fig.2: Schema electrica,exemple de inmultire

Pentru efectuarea lucrarii am folosit microcontrolerul ATMega 32, 7SEG-BCD si switch-ul


(DIPSWC_8). Am conectat la fiecare port de intrare (PORTA,PORTB) cite un switch ,iar la iesire am
conectat 4 BCD-uri. Cu switch alegem combinatia ce dorim sa o introducem. Pentru a vizualiza valorile
hexazecimale ce corespund combinatiei introdusa la intrari de asemenea conectam BCD-uri.Schema
functioneaza astfel: introducem cite o combinatie la fiecare intrare. Conform codului incarcat in
microcontroler, se va efectua inmultirea iar solutia va fi transmisa la iesire(PORTC(val.high),
PORTD(val low))si vizualizata.

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).

S-ar putea să vă placă și