Sunteți pe pagina 1din 44

Limbaje formale i translatoare (Compilatoare)

Aceasta este ultima etap a procesului de


compilare.
Pe baza unei reprezentri intermediare a
programului surs, ea genereaz un program
echivalent,
scris
n
limbajul
main
al
procesorului int.
Spre deosebire de restul etapelor compilrii,
generarea codului final este dependent de
maina int:
Arhitectura difer de la un tip de main la altul.
Fiecare tip de procesor are propriul set de instruciuni.
Fiecare tip de arhitectur are particulariti care trebuie
luate n considerare.

Generarea codului final trebuie s duc la obinerea unui fiier


executabil.
Regulile pe care trebuie s le respecte un fiier executabil pe o
anumit arhitectur (relativ la procesor i la sistemul de operare)
sunt specificate n ceea ce se numete application binary
interface (ABI).
ABI descrie:
Instruciunile procesorului int;
modul de utilizare al regitrilor;
conveniile de apel: modul n care funciile primesc parametrii de
la apelant, precum i modul n care ele pot returna valori
apelantului;
programarea instruciunilor (pentru instruciunile care pot fi
executate n paralel);
organizarea memoriei;
formatul fiierului executabil, .a.

Procesorul este format din:

O unitate central de procesare (CPU) principal;


Dou co-procesoare:
Unul pentru operaiile cu numere reale;
Unul pentru gestiunea memoriei.

Dimensiunea unui cuvnt este de 32 de bii (numrul de


bii pe care un CPU l poate procesa la un moment dat).
Procesorul are un numr de 32 de regitri, fiecare de
dimensiunea unui cuvnt, unii cu destinaii speciale, alii
pentru utilizarea general.
Co-procesorul dedicat operaiilor cu numere reale are i el
32 de regitrii.
Toate instruciunile sunt codate printr-un singur format,
de lungimea unui cuvnt.
Toate operaiile cu date sunt de tip registru la registru.
Referinele la memorie sunt numai de tip load/store.
4

Maina ofer un singur mod de adresare:


c (rx)
Accesarea locaiei de la offsetul c (pozitiv sau
negativ), relativ la adresa de memorie stocat
n registrul rx.
Instruciunile load i store opereaz numai
asupra datelor aliniate: o cantitate este
aliniat numai dac adresa sa este un
multiplu al dimensiunii sale n octei.

Spaiul de adrese al unui program pe o main MIPS


este format din mai multe segmente:
n partea de jos este segmentul de text (conine
instruciunile programului) dimensiune fix, setat
la compilare, care nu se poate modifica.
Urmeaz apoi segmentul de date statice (conine
obiectele a cror adres i dimensiune sunt
cunoscute compilatorului i link-editorului n
momentul compilrii) dimensiune fix, setat la
compilare, care nu se poate modifica.
n partea urmtoare se afl segmentul de date
dinamice numit i heap (dimensiunea sa crete n
funcie de appelurile de alocare de memorie).
n partea de sus a spaiului de adrese este stiva
programului. Aceasta crete n jos, ctre heap.
7

SPIM este un simulator pentru MIPS32.


Permite citirea i execuia de programe scrise
n limbaj de asamblare.
Nu ruleaz executabile (programe binare
compilate).

main:

.text
.globl main
li
li
addu
la
li
syscall
move
li
syscall
la
li
syscall
li
syscall
.data

egal:
linie_noua:

$t1, 1
$t2, 32
$t3,$t1,$t2
$a0, egal
$v0, 4
$a0, $t3
$v0, 1
$a0, linie_noua
$v0, 4
$v0, 10

.asciiz
.asciiz

"="
"\n"

10

%{

#include <stdio.h>

FILE * yyies = NULL;

int EsteCorecta = 1;
char msg[50];

int Prima = 0;

%}

%token TOK_PLUS TOK_MINUS TOK_MULTIPLY TOK_DIVIDE TOK_LEFT TOK_RIGHT


%token TOK_NUMBER

%start S

%left TOK_PLUS TOK_MINUS


%left TOK_MULTIPLY TOK_DIVIDE

11

%%
S:
|
E ';' S
{

fprintf(yyies,"\tla\t$a0, egal\n\tli\t$v0,
4\n\tsyscall\n\tmove\t$a0, $t1\n\tli\t$v0, 1\n\tsyscall\n");
fprintf(yyies, "\tla\t$a0, linie_noua\n\tli\t$v0,
4\n\tsyscall\n");
Prima = 0;
}
|
error ';' S
{ EsteCorecta = 0; }
;

12

E : E TOK_PLUS E
{
fprintf(yyies, "\tadd\t$t1,$t1,$t2\n");
Prima = 1;
}
|
E TOK_MINUS E
{
fprintf(yyies, "\tsub\t$t1,$t1,$t2\n");
Prima = 1;
}
|

13

E TOK_MULTIPLY E
{
if(Prima == 2)
{
fprintf(yyies,
fprintf(yyies,
}
else
{
fprintf(yyies,
fprintf(yyies,
}
Prima = 1;
}

"\tmult\t$t1,$t2\n");
"\tmflo\t$t1\n");

"\tmult\t$t2,$t3\n");
"\tmflo\t$t2\n");

14

E TOK_DIVIDE E
{
if($3 == 0)
{
sprintf(msg,"%d:%d Eroare semantica: Impartire la zero!", @1.first_line, @1.first_column);
yyerror(msg);
YYERROR;
}
else
{
if(Prima == 2)
{
fprintf(yyies, "\tdiv\t$t1,$t2\n");
fprintf(yyies, "\tmflo\t$t1\n");
}
else
{
fprintf(yyies, "\tdiv\t$t2,$t3\n");
fprintf(yyies, "\tmflo\t$t2\n");
}
Prima = 1;
}
}
|

15

TOK_NUMBER
{

;
%%

if(Prima == 0)
{
fprintf(yyies, "\tli\t$t1, %d\n", $1);
Prima = 1;
}
else if(Prima == 1)
{
fprintf(yyies, "\tli\t$t2, %d\n", $1);
Prima = 2;
}
else
{
fprintf(yyies, "\tli\t$t3, %d\n", $1);
Prima = 3;
}

16

int main()
{
yyies = fopen("math.s","w");
fprintf(yyies, "\t.text\n\t.globl main\nmain:\n");
yyparse();

fprintf(yyies,"\tli\t$v0, 10\n\tsyscall\n\t.data\negal:\t\t.asciiz
\"=\"\nlinie_noua:\t.asciiz\t\"\\n\"");
fclose(yyies);

if(EsteCorecta == 1)
{
printf("CORECTA\n");
}

return 0;

17

int yyerror(const char *msg)


{
printf("Error: %s\n", msg);
return 1;
}

18

Ex: 2*3+4+2*2-1-5+2+3*2-4/2+3;
.text
.globl main
main:
li
$t1, 2
li
$t2, 3
mult
$t1,$t2
mflo
$t1
li
add

$t2, 4
$t1,$t1,$t2

li
li
mult
mflo

$t2, 2
$t3, 2
$t2,$t3
$t2

19

Ex: 2*3+4+2*2-1-5+2+3*2-4/2+3;
add

$t1,$t1,$t2

li
sub

$t2, 1
$t1,$t1,$t2

li
sub

$t2, 5
$t1,$t1,$t2

li
add

$t2, 2
$t1,$t1,$t2

li
li
mult
mflo

$t2, 3
$t3, 2
$t2,$t3
$t2

add

$t1,$t1,$t2

20

Ex: 2*3+4+2*2-1-5+2+3*2-4/2+3;

li
li
div
mflo

$t2, 4
$t3, 2
$t2,$t3
$t2

sub

$t1,$t1,$t2

li
add

$t2, 3
$t1,$t1,$t2

21

la
li
syscall

$a0, egal
$v0, 4

move
li
syscall

$a0, $t1
$v0, 1

la
li
syscall

$a0, linie_noua
$v0, 4

$v0, 10

li
syscall

.data

egal:
linie_noua:

.asciiz
.asciiz

"="
"\n"

22

23

Intrare

2*3+4+2*2-1-5+2+3*2-4/2+3;

Look ahead

Stiva

24

Intrare

2*3+4+2*2-1-5+2+3*2-4/2+3;

Look ahead

NR

Stiva

25

Intrare

2*3+4+2*2-1-5+2+3*2-4/2+3;

Look ahead

Stiva

NR

26

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
*

Stiva

li

$t1, 2

27

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
NR

Stiva

*
E

li

$t1, 2

28

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
+

Stiva

NR
*
E

li

$t1, 2

29

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
+

Stiva

li

$t2, 3

li

$t1, 2

*
E

30

Intrare
Look ahead
Stiva
E

2*3+4+2*2-1-5+2+3*2-4/2+3;
+
mult
mflo

$t1,$t2
$t1

31

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
NR

Stiva

+
E

mult
mflo

$t1,$t2
$t1

32

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
+

Stiva

NR
+

mult
mflo

$t1,$t2
$t1

33

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
+

Stiva

E
+

li

$t2, 4

mult
mflo

$t1,$t2
$t1

34

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
+

Stiva

add

$t1,$t1,$t2

35

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
NR

Stiva

+
E

add

$t1,$t1,$t2

36

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
*

Stiva

NR
+
E

add

$t1,$t1,$t2

37

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
*

Stiva

li

$t2, 2

add

$t1,$t1,$t2

+
E

38

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
NR

Stiva

*
E

li

$t2, 2

add

$t1,$t1,$t2

+
E

39

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
-

Stiva

NR
*
E

li

$t2, 2

add

$t1,$t1,$t2

40

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
-

Stiva

li

$t3, 2

li

$t2, 2

add

$t1,$t1,$t2

*
E
+

41

Intrare
Look ahead
Stiva
E

2*3+4+2*2-1-5+2+3*2-4/2+3;
mult
mflo

$t2,$t3
$t2

add

$t1,$t1,$t2

42

Intrare
Look ahead

2*3+4+2*2-1-5+2+3*2-4/2+3;
-

Stiva

add

$t1,$t1,$t2

.a.m.d.

43

http://dragonbook.stanford.edu/lecturenotes/Stanford-CS143/19-Final-CodeGeneration.pdf
http://www.cs.wright.edu/~tkprasad/courses
/cs781/L23CG.pdf
http://cs.oberlin.edu/~jdonalds/331/phase0
4MIPS.html
http://programmedlessons.org/AssemblyTut
orial/index.html
http://www.mrc.uidaho.edu/mrc/people/jff/
digital/MIPSir.html
44

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