Anexa B Anexa D
Anexa C

Codul virtual propus pentru lucrarile de laborator


C.1. Instructiuni de incarcare in stiva

C.1.1. LOD nivel adrel

Incarca in varful stivei de lucru valoarea aflata la adresa calculata pe baza argumentelor.

i = VBAZA
while nivel <> BAZA[i].LEVEL do
i = i - 1
endwhile
adr = BAZA[i].BLOC + adrel     //(**)
while STIVA[adr].TIP_NOD = 'adresa ' do
adr = STIVA[adr].INFO
endwhile
SP = SP + 1
STIVA[SP] = STIVA[adr]
NI = NI + 3
 
C.1.2. LODI iconst

Incarca in varful stivei de lucru constanta aflata in pozitia iconst din TAB_CONST.

SP = SP + 1
STIVA[SP] = TAB_CONST[iconst]
NI = NI + 2
 
C.1.3. LODA nivel adrel

Incarca in varful stivei de lucru adresa calculata pe baza argumentelor.

SP = SP + 1
i = VBAZA
while nivel <> BAZA[i].LEVEL do
i = i - 1
endwhile
adr = BAZA[i].BLOC + adrel
STIVA[SP].TIP_NOD = 'adresa '
STIVA[SP].INFO = adr
NI = NI + 3

C.1.4. LODX nivel adrel

Ca si LOD, dar la calculul adresei se include si continutul registrului de index. Implementarea este similara cu cea a instructiunii LOD, singura modificare apare in linia (**) si anume:

adr = BAZA[i].BLOC + adrel + RX

C.1.5. COPI

Se creaza un nod nou in varful stivei de lucru completat cu continutul vechiului varf.

SP = SP + 1
STIVA[SP] = STIVA[SP - 1]
NI = NI + 1

C.2. Instructiuni de extragere din stiva
 

C.2.1. STO

Depune valoarea aflata in varful stivei de lucru la adresa indicata de nodul de sub varf si apoi elimina doua noduri din stiva .

SP = SP - 2
adr = STIVA[SP + 1].INFO
while STIVA[adr].TIP_NOD = 'adresa ' do
adr = STIVA[adr].INFO
endwhile
STIVA[adr] = STIVA[SP + 2]
NI = NI + 1


C.2.2. MVRX

Muta in registrul de index valoarea din varful stivei de lucru.

RX = STIVA[SP].INFO
SP = SP - 1
NI = NI + 1
 
C.2.3. RED

Elimina un nod din stiva de lucru.

SP = SP - 1
NI = NI + 1


C.3. Instructiuni de salt
 

C.3.1. UJP adr

Salt neconditionat la instructiunea aflata la adresa adr in TAB_COD.

NI = adr
 


C.3.2. FJP adr

Daca valoarea din varful stivei este 0 (fals) se realizeaza salt la instructiunea aflata la adresa adr in TAB_COD; in caz contrar, se continua executia cu instructiunea imediat urmatoare. In ambele cazuri se elimina valoarea din varful stivei.

if STIVA[SP] = 0 then
NI = adr
else
NI = NI + 2
endif
SP = SP - 1
 
 
C.4. Instructiuni de test
 

C.4.1. LES

Se testeaza daca valoarea de sub varful stivei de lucru se afla in relatia '<' cu valoarea din varful stivei. Apoi cele doua valori se elimina si in locul lor se depune valoarea 1 (adevarat) - daca relatia exista, respectiv 0 - daca relatia nu exista .

SP = SP - 1
if STIVA[SP].INFO < STIVA[SP + 1].INFO then
STIVA[SP].INFO = 1
else
STIVA[SP].INFO = 0
endif
STIVA[SP].TIP_NOD = 'intreg'
NI = NI + 1


C.4.2. - C.4.6. LEQ, GRT, GEQ, EQU, NEQ

Ca si LES, dar operatorii de relatie sunt respectiv: <= , >, >= , =  si <>.
 

C.5. Instructiuni aritmetice

C.5.1. ADD

Insumeaza valoarea de sub varful stivei cu valoarea din varf, elimina operanzii din stiva si depune rezultatul in varf.

SP = SP - 1
STIVA[SP].INFO = STIVA[SP].INFO + STIVA[SP + 1].INFO
*eventuale verificari privind depasirea limitelor de reprezentare a numerelor
NI = NI + 1
Obs: tipul rezultatului obtinut depinde de tipul operanzilor. In majoritatea cazurilor operanzii sunt de acelasi tip (la generarea de cod este prevazuta efectuarea conversiilor daca operanzii sunt diferiti ca tip). Un caz particular insa , il constituie calculul de adresa pentru elementele de tablouri sau pentru campuri de structura (v. Lucrarea nr.11), cand apare adunarea unei adrese cu un deplasament (numar intreg). In aceste situatii tipul rezultatului va fi 'adresa'.
 

C.5.2. - C.5.5. SUB, MUL, DIV, MOD

Ca si ADD, dar operatorii aritmetici sunt respectiv: -, *, / si modulo. La impartiri se vor efectua in plus verificari privind valoarea impartitorului.
 

C.6. Instructiuni pentru lucrul cu subprograme
 

C.6.1. RBM dim_var nr_loc

Rezervare marcaj de bloc in stiva de lucru, inaintea rezolvarii unui apel de subprogram. Argumentul nr_loc poate fi: 2 - pentru functii, respectiv 1 - pentru proceduri. Marcajul de bloc va servi pentru:

Pana la rezolvarea propriu-zisa a apelului (executia unei instructiuni CALL), marcajul de bloc pastreaza valoarea dim_var, necesara pentru rezervarea in stiva a spatiului pentru variabilele locale ale subprogramului.
Se mentioneaza faptul ca deasupra marcajului de bloc, in stiva de lucru se va afla blocul rezervat subprogramului apelat. Prin urmare, in cazul functiilor, locatia in care se memoreaza rezultatul returnat se afla la deplasament (-2) fata de inceputul blocului de lucru. Acesta este motivul pentru care campul ADREL din TS s-a completat cu valoarea -2 la numele de functii (v. Lucrarea nr.8).
SP = SP + nr_loc
STIVA[SP].INFO = dim_var
NI = NI + 3
 
C.6.2. CALL adr_salt nr_par nivel

Apel de subprogram: completeaza un nod nou in stiva BAZA, rezerva in stiva de lucru spatiu pentru variabilele locale, memoreaza adresa de revenire si executa saltul la codul subprogramului apelat.

VBAZA = VBAZA + 1
BAZA[VBAZA].LEVEL = nivel
BAZA[VBAZA].BLOC = SP - nr_par + 1
SP = SP + STIVA[BAZA[VBAZA].BLOC -1].INFO
STIVA[BAZA[VBAZA].BLOC - 1].INFO = NI + 4
NI = adr_salt


C.6.3. RET

Revenire dintr-un subprogram.

SP = BAZA[VBAZA].BLOC - 2
NI = STIVA[SP + 1]
VBAZA = VBAZA - 1
 
C.6.4. FCALL adr_salt nr_par nivel

Este o instructiune fictiva utilizata pentru rezolvarea apelurilor de subprograme care apar intr-un text sursa inainte de a se cunoaste adresa de start a subprogramelor respective (v. Lucrarea nr.11). Practic toate instructiunile FCALL din TAB_COD sunt inlocuite cu instructiuni CALL, inainte ca programul obiect sa fie lansat in executie. Se poate spune, deci, ca aceasta instructiune nici nu este recunoscuta de masina virtuala.
 
 

C.7. Instructiuni de oprire a programului
 

C.7.1. STOP

Oprire normala a programului.

ST = 'stop'


C.7.2. ERR cod

Forteaza oprirea programului, pozitionand registrul de stare pe err si incarcand in registrul indicator de eroare valoarea cod.

ST = 'err'
IE = cod

C.8. Instructiuni de intrare-iesire
 

C.8.1. INP tip

Citire a unei valori de tipul indicat si depunerea ei in varful stivei de lucru.

SP = SP + 1
*citeste de la consola o valoare de tipul indicat la argument
STIVA[SP].TIP = tip
STIVA[SP].INFO = *valoarea citita
NI = NI + 2


C.8.2. OUT

Valoarea din varful stivei se afiseaza pe ecran si apoi se elimina din stiva .

*afiseaza STIVA[SP].INFO
SP = SP - 1
NI = NI + 1

C.9. Instructiuni de conversie

C.9.1. CONV tip nr_loc

Realizeaza conversia la tipul indicat a valorii aflate in varful stivei (daca nr_loc este 0) sau sub varful stivei (daca nr_loc este 1).

*conversie la tip a continutului locat iei STIVA[SP - nr_loc]
NI = NI + 3

C.10. Instructiuni logice

C.10.1. AND

Se aplica operatorul 'si' logic asupra a doua valori din varful stivei.

SP = SP - 1
STIVA[SP].INFO = STIVA[SP].INFO and STIVA[SP + 1].INFO
NI = NI + 1


C.10.2. OR

Ca si AND, dar se aplica operatorul 'sau' logic.
 

C.10.3. NOT

Se aplica negatia logica asupra valorii din varful stivei.

STIVA[SP].INFO = not STIVA[SP].INFO
NI = NI + 1
 
 

Anexa B Anexa D