Bun venit la ora a II-a )nu uitati sa lucrati si ora I)
CUM ARATA CODURILE RULATE DE MASINA VIRTUALA
In aceasta postare voi prezenta o serie de secvente de cod foarte simple,
in limbajul masinii virtuale.
Scopul este sa intelegem cum arata codurile care vor fi rulate de masina virtuala.
Pentru fiecare voi scrie un mic program in Simple si voi prezenta codul echivalent care va rula pe masina virtuala.
Nota: Aici, mai jos, este scris in_int si nu read_int dar e aceeasi instructiune!
Nota: Aici, mai jos, este scris out_int si nu write_int dar e aceeasi instructiune!
Am inclus si fiserele sursa .sim "echivalente" cu codurile de mai jos:
Exemplul 0:
Fisier: p0.sim
let
integer x.
in
end
Codul:
0: data 0 // Nu ridic varful stivei
1: halt 0 // ma opresc
Exemplul 1:
Fisier: p1.sim
0: data 0 // Am o singura variabila la baza stivei, pozitia 0
1: in_int 0 // Citesc o valoare de la tastatura, de la prompter
si o pun pe stiva la adresa variabilei, aici adresa 0
2: ld_var 0 // Incarc in varful stivei continutul variabilei de la adresa 0
3: out_int 0 // iau ultima valoare din stiva si o afisez pe consola
4: halt 0 // ma opresc
Exemplul 2:
Fisier: p2.sim
let
integer x.
in
read x;
x := x+1;
write x;
end
Codul :
0: data 0 // Am o singura variabila la baza stivei, pozitia 0, variabila x
1: in_int 0 // Citesc o valoare de la tastatura, de la prompter
si o pun pe stiva la adresa variabilei, aici adresa 0
2: ld_var 0 // Incarc variabila de la adresa 0 in varful stivei
3: ld_int 1 // Incarc in varful stivei un intreg: pe 1
4: add 0 // Scot 2 valori din stiva si le adun , obtin in virful stivei x+1
5: store 0 // Stochez ce e in varful stivei la adresa lui x, adica adresa 0
6: ld_var 0 // Incarc iar in varful stivei valoarea variabilei de la adresa 0
7: out_int 0 // iau ultima valoare din stiva si o afisez pe consola
8: halt 0 // ma opresc
Exemplul 3:
Fisier: p3.sim
let
integer x.
in
read x;
if (x=0)
then
write 0;
else
write 1;
fi;
end
Codul:
0: data 0 // Am o singura variabila la baza stivei, pozitia 0, variabila x
1: in_int 0 // Citesc o valoare de la tastatura, de la prompter
si o pun pe stiva la adresa variabilei, aici adresa 0
2: ld_var 0 // Incarc in varful stivei intai valoare var de la adresa 0, x-ul
3: ld_int 0 // Incarc in varful stivei apoi valoare numarului intrg 0
4: eq 0 // Le scot pe ambele din stiva, le compar, pun rezultatul in stiva
5: jmp_false 9 // Daca comparatia da False,0, sar la ramura else, adresa 9
// Altfel continui.
6: ld_int 0 // Incarc in stiva valoarea intreaga, constanta 0
7: out_int 0 // Afisez ultima valoare din stiva
8: goto 11 // Sar la Halt pt oprire.
// De aici incepe ramura else:
9: ld_int 1 // Incarc in varful stivei valoarea 1
10: out_int 0 // Afisez ultima valoare din stiva, adica 1
11: halt 0 // Stop.
Nota: Incarc in varful stivei este un PUSH, indicatorul de stiva se ridica cu aceasta ocazie.
Exemplul 4:
Fisier: p4.sim
let
integer x.
in
x := 100;
while x > 10 do
x := x -1;
write x;
end;
end
Codul:
0: data 0 // Declar ca am o variabila la baza stivei.
1: ld_int 100 // PUSH 100, pun in vf stivei valoarea 100
2: store 0 // O scot de acolo si o stochez la adresa var. x, adresa 0
3: ld_var 0 // Incarc iar in varful stivei valoarea var. de la adresa 0
4: ld_int 10 // Peste ea, incarc in varful stivei valoarea constanta 10
5: gt 0 // Compar daca valoarea variabilei e mai mare ca a const.
// Practic scot ultimele 2 valori din stiva si le compar.
// Pun rezultatul tot in stiva.
6: jmp_false 14 // Iau val din varful stivei, daca e un zero, false, sar la stop
7: ld_var 0 // Incarc iar in vf strivei valoarea var de la dresa 0
8: ld_int 1 // Incarc peste ea valoarea constantei 1
9: sub 0 // Scot doua valori, scad din cea de jos pe cea de sus
// si pun diferenta rezultata tot in stiva.
10: store 0 // iau ce gasesc in vf stivei, diferenta si o stochez la adr. 0
// Practic, am pus in locatia lui xvaloarea x-1
11: ld_var 0 // Incarc iar in varful stivei valoarea lui x de la adr. 0
12: out_int 0 // Scot din stiva o valoare si o afisez.
13: goto 3 // Reiau bucla de la adresa 3.
14: halt 0 // cand ajung prin slat aici, stop.
Exemplul 5:
Fisier: p5.sim
let
integer n, i, fact.
in
read n;
i := 2;
fact := 1;
while i < n + 1 do
fact := fact * i;
i := i + 1;
end;
write fact;
end
Acest program calculeaza n! ca produs al numerelor de la 1 la n.
0: data 2 // Peste pozitia 0 se aloca si pozitiile 1 si 2 din stiva ca variabile
1: in_int 0 // Citim valoare avriabilei din pozitia 0, si o stocam acolo
2: ld_int 2 // Incarcam in stiva constanta 2
3: store 1 // Si de acolo o luam si o stocam in variabila 1, de la adresa 1
4: ld_int 1 // Incarcam in stiva constanta 1
5: store 2 // O stocam la adresa 2, a celei de-a treia variabile
// A doua variabila va fi contorul care creste de la 1 la n.
// A treia variabila va fi produsul, de aceea il initializez cu 1
// Prima variabila e numarul n al carui factorial il calculez.
6: ld_var 1 // Incarc in stiva valoarea variabilei de la adresa 1, contorul
7: ld_var 0 // Adaug in stiva, deasupra, valoarea primei variabile, maximul
8: ld_int 1 // Pun in stiva, deasupra , o constanta 1
9: add 0 // Adun acel maxim, n, cu constanta 1, obtin n+1
10: lt 0 // Compar i, contorul, var a II-a cu suma n+1 (var I + o unitate)
// Comparatia este practic intre i si n+1 din sursa, cu semn <
11: jmp_false 21 // Daca este fals, adica i > n+1 sar la adresa 21, dupa bucla
// Aici intru in bucla.
12: ld_var 2 // Incarc in vf stivaei valoarea variabilei a 3-a, produsul fact
13: ld_var 1 // Incarc in vf stivaei valoarea variabilei a 2-a, contorul i
14: mult 0 // Scot ultiemele doua valori si le inmultesc
15: store 2 // Stochez la adresa variabilei a treia , noul produs
16: ld_var 1 // Pun in stiva copia contorului de la adresa 1
17: ld_int 1 // Peste ea pun in stiva constanta 1
18: add 0 // Fac suma ultiemlor 2 valori din stiva, am contorul+1
19: store 1 // Il stochez la adresa contorului
20: goto 6 // Reiau bucla de la adresa 6
21: ld_var 2 // Incarc in varful stivei valoare variabilei de la adresa 2
22: out_int 0 // Scot valoare din vf stivei si o afisez.
23: halt 0 // Stop.
Exercitiul 6:
Fisier: p6.sim
0: data 2
1: in_int 0
2: in_int 1
3: ld_var 0
4: ld_var 1
5: add 0
6: ld_int 2
7: div 0
8: store 2
9: ld_var 2
10: out_int 0
11: halt 0
Intrebare de control:
Ce calculeaza codul de mai sus:
- Suma unor numere
- Produsul unor numere
- Media unor numere, trunchiata la un intreg
- maximul unor numere
Comentati codul rand cu rand !
Exercitiul 7:
Fisier: p7.sim
0: data 0
1: ld_int 1
2: jmp_false 7
3: in_int 0
4: ld_var 0
5: out_int 0
6: goto 1
7: halt 0
Intrebare de control:
Ce calculeaza codul de mai sus:
- citiri repetate intr-o bucla
- scrieri repetate intr-o bucla
- citire si scriere repetate intr-o bucla
- maximul a doua numere
Pauza !
Atentie: Antrenati-va la acest gen de exercitii imediat ce terminati compilatorul.
Intrucat modul de generare a acestor coduri de catre compilator este oarecum obscur il vom explica in saptamanile care urmeaza.
Niciun comentariu:
Trimiteți un comentariu