ghid utilizare qtspim

38
QtSPIM și MARS - ghid utilizare 1. Prezentare generalǎ QtSpim și MARS sunt programe destinate asamblǎrii și simulǎrii programelor scrise ȋn limbajul de asamblare MIPS IV. Arhitectura de calculator simulatǎ are forma din Fig. 1. Fig. 1 Blocurile prezentate ȋn Fig. 1 au urmǎtoarele semnificații: CPU – procesorul central este un procesor pentru realizarea operațiilor aritmetice și logice asupra numerelor reprezentate ȋn format virgulǎ fixǎ. Principalele componente sunt: ALU – unitatea aritmetico/logicǎ pentru numere ȋntregi ȋn virgulǎ fixǎ; Multiplic/divid – realizeazǎ ȋnmulțirea și ȋmpǎrțirea pentru numere ȋntregi ȋn format virgulǎ fixǎ; 1

Upload: corleone93

Post on 18-Jan-2016

39 views

Category:

Documents


0 download

DESCRIPTION

Ghid utilizare QtSPIM

TRANSCRIPT

Page 1: Ghid utilizare QtSPIM

QtSPIM și MARS - ghid utilizare

1. Prezentare generalǎ

QtSpim și MARS sunt programe destinate asamblǎrii și simulǎrii programelor scrise ȋn limbajul de asamblare MIPS IV.

Arhitectura de calculator simulatǎ are forma din Fig. 1.

Fig. 1

Blocurile prezentate ȋn Fig. 1 au urmǎtoarele semnificații:

CPU – procesorul central este un procesor pentru realizarea operațiilor aritmetice și logice asupra numerelor reprezentate ȋn format virgulǎ fixǎ. Principalele componente sunt:

ALU – unitatea aritmetico/logicǎ pentru numere ȋntregi ȋn virgulǎ fixǎ; Multiplic/divid – realizeazǎ ȋnmulțirea și ȋmpǎrțirea pentru numere ȋntregi ȋn format

virgulǎ fixǎ; 32 registre generale – pe 32 biți fiecare; pǎstreazǎ operanzii și rezultatele; registrul

$0 nu poate fi utilizat decȃt pentru citire deoarece conține constanta 0. Ȋn cadrul compilatorului și alte registre joacǎ roluri speciale și nu pot fi folosite ȋn programele scrise de utilizator.

1

Page 2: Ghid utilizare QtSPIM

HI, LO reprezintǎ jumǎtǎțile unui registru special pe 64 biți utilizat pentru pǎstrarea rezultatului ȋnmulțirii a doi operanzi pe 32 biți.

Coprocesorul 1 – utilizat pentru operații ȋn format virgulǎ mobilǎ. Este alcǎtuit din: 32 registre pe 32 biți fiecare; Unitatea aritmeticǎ pentru numere reprezentate ȋn virgulǎ mobilǎ.

Coprocesorul 0 – utilizat pentru prelucrarea unor date speciale legate de starea celorlalte blocuri sau apariția unor anomalii ȋn funcționare.

Memoria – memorie RAM care conține atȃt operanzi și rezultate pe 32 biți cȃt și instrucțiuni și date specifice procesului de compilare/simulare.

2. Structura memoriei din punctul de vedere QtSPIM (MARS)

Harta memoriei cu punerea ȋn evidențǎ a segmentelor de memorie utilizate de QtSPIM este prezentatǎ ȋn Fig. 2.

Fig. 2

3. Elemente ale programelor pentru asamblor

Programul scris pentru asamblorul QtSpim poate conține pe lȃngǎ instrucțiunile propriuzise ale limbajului și alte elemente:

Directive de nivel ȋnalt:

.text - indicǎ faptul cǎ toate elementele (de obicei instrucțiuni MIPS) care urmeazǎ sunt pǎstrate ȋn segmentul de text pus la dispoziția utilizatorului;

.data - indicǎ faptul cǎ toate elementele care urmeazǎ sunt pǎstrate segmentul de date; .globl sym – declarǎ cǎ simbolul sys este global adicǎ poate fi citit și din alte fișiere.

Definiții de date : .word w1,…,wn - ȋnregistreazǎ n combinații binare pe 32 biți ȋn cuvinte de memorie

consecutive; .half h1,…,hn - ȋnregistreazǎ n combinații binare pe 16 biți ȋn semicuvinte de

memorie consecutive; .byte b1,…,bn - ȋnregistreazǎ n combinații binare pe 8 biți ȋn octeți de memorie

consecutivi;

2

Page 3: Ghid utilizare QtSPIM

.ascii “str” - ȋnregistreazǎ șirul de caractere ASCII dintre ghilimele ȋn memorie; caracterele speciale de forma \n, \t respectǎ regulile din limbajul C;

.asciiz “str” - ȋnregistreazǎ șirul de caractere ASCII dintre ghilimele ȋn memorie și ȋncheie cu caracterul nul;

.float f1,…,fn - ȋnregistreazǎ n numere ȋn format virgulǎ mobilǎ simplǎ precizie ȋn cuvinte de memorie consecutive;

.double d1,…,dn - ȋnregistreazǎ n numere ȋn format virgulǎ mobilǎ dublǎ precizie ȋn cuvinte de memorie consecutive;

.space n – rezervǎ ȋn memorie n octeți succesivi; .align n – aliniazǎ data care urmeazǎ la limita 2n octeți; .align 0 dezactiveazǎ automat

alinierea implicatǎ de .half, .word, etc. pȃnǎ la urmǎtoarea directivǎ .data. Pseudoinstrucțiuni:

Nu fac parte din setul de instrucțiuni MIPS și au fost introduse pentru a simplifica scrierea programelor și a face programele mai clare. Asamblorul convertește o pseudoinstrucțiune ȋn una sau douǎ instrucțiuni MIPS.

mov $rd,$rs - permite transferul conținutului registrului sursǎ rs ȋn registrul destinație rd; existǎ mai multe variante prin care putem substitui aceastǎ pseudoinstrucțiune printr-o instrucțiune MIPSa) add $rd, $rs, $0b) or $rd, $rs, $0c) addi $rd, $rs, 0

li $rd, imediat – asigurǎ ȋncǎrcarea registrului destinație $rd cu valoarea imediat. Substituirea cu o instrucțiune MIPS se face ȋn funcție de valoarea transferatǎ ȋn registru. Dacǎ imediat este o valoare pe cel mult 16 biți (small), substituția se va face prin:a) addi $rd, $0, smallb) ori $rd, $0, small

Dacǎ imediat este o valoare pe 32 biți (big), substituția se va face prin instrucțiunilelui $rd, bigH

ori $rd,$rd, bigL

unde bigH respectiv bigL reprezintǎ semicuvȃntul superior respectiv semicuvȃntul inferior al valorii transferate.

la $rd, adresa - ȋncarcǎ ȋn registrul destinație $rd o adresǎ pe 32 biți. Substituirea se face ca și ȋn cazul pseudoinstrucțiunii precedente pentru valori mari, adicǎ:

lui $rd, bigH

ori $rd, $rd, bigL

se observǎ cǎ aceastǎ pseudoinstrucțiune nu este necesarǎ decȃt pentru a face mai clarǎ natura datei ȋncǎrcate ȋn registru (datǎ sau adresǎ).

Pseudoinstrucțiuni pentru ramificare – au fost introduse deoarece limbajul MIPS are doar douǎ instrucțiuni de ramificare beq și bne ceea ce ȋngreuneazǎ ȋn general scrierea programelor. Au fost definite 4 pseudoinstrucțiuni de ramificare:

o bge $r1,$r2, eticheta - ramificarea se realizeazǎ numai dacǎ $r1$r2; se substitue prin:slt $at, $r1,$r2beq $at, $$0, eticheta

o bgt $r1,$r2, eticheta - ramificarea se realizeazǎ numai dacǎ $r1>$r2; se substitue prin:slt $at, $r1,$r2bne $at, $$0, eticheta

o ble $r1,$r2, eticheta - ramificarea se realizeazǎ numai dacǎ $r2$r1; se substitue prin:slt $at, $r1,$r2beq $at, $$0, eticheta

3

Page 4: Ghid utilizare QtSPIM

o blt $r1,$r2, eticheta - ramificarea se realizeazǎ numai dacǎ $r2>$r1; se substitue prin:slt $at, $r1,$r2bne $at, $$0, eticheta

instrucțiuni propriuzise ale limbajului de asamblare – fac parte din setul de instrucțiuni ale procesoarelor MIPS;

comentarii – orice șir de caractere cuprins ȋntre caracterul # și sfȃrșitul liniei.

4. Structura generalǎ a unui program pentru QtSPIM/MARS

Structura tipicǎ a unui program ȋn limbaj de de asamblare este:

# structura tipica a programului in limbaj de asamblare

.text # urmeaza sectiunea de cod .globl main # punctul de start: trebuie sǎ fie global

main: # eticheta obligatorie

# cod program utilizator obligatoriu

.data # sectiunea de date

# date utilizator

Observație! Utilizarea directivelor, pseudoinstrucțiunilor și definițiile de date nu sunt obligatorii. Comentariile sunt recomandate pentru a face programele inteligibile.

5. Utilizarea registrelor generale

Registrele $0, $1, $26, $27 și $31 sunt rezervate pentru diverse funcții ale asamblorului și nu pot fi suprascrise de cǎtre utilizator. Registrul $0 conține constanta 0 pe 32 biți și poate fi utilizatǎ ȋn aplicațiile utilizatorului. Registrul $1 se simbolizeazǎ $at, registrele $26, $27 (rezervate pentru lucrul cu sistemul de operare) se simbolizeazǎ $k0, $k1 iar $31 se simbolizeazǎ $ra.

Registrele $2 și $3 sunt utilizate pentru apelul unor funcții de sistem și sunt simbolizate ca $v0 respectiv $v1.

Registrele $4, $5, $6, $7 pot fi utilizate ca argumente pentru apelul funcțiilor de sistem sau pǎstrarea unor valori returnate. Sunt simbolizate $a0, $a1,$ a2, $a3 și pot fi utilizate și ȋn alte scopuri.

Registrele $8 - $25 sunt registre utilizate ȋn aplicațiile utilizatorilor. Registrele $8 - $15, $24 și $25 sunt numite registre temporare și se noteazǎ $t0 - $t9. Registrele $16 - $23 sunt simbolizate ca $s0 - $s7.

Registrele $28, $29, $30 conțin informații specifice activitǎții asamblorului și se noteazǎ $gp, $sp, $fp.

6. Utilizarea aplicației QtSPIM

Editarea programelor utilizator se realizeazǎ cu ajutorul unui editor de texte (se recomandǎ Notepad++) Dupǎ activarea programului QtSPIM, pe ecran va apare o fereastrǎ ȋmpǎrțitǎ ȋn mai multe zone cu

funcții specifice, ca ȋn Fig. 3.

4

Page 5: Ghid utilizare QtSPIM

Fig. 3

Reinitializeaza Reinitializeaza simularesi reicarca fisier tipareste simularea pauza pas cu pas

Fig. 4

Incarca salveaza sterge pornire stop helpFisier registre simulare

Registre generale zona text

Fig. 5

Registre zona date virgula mobila

Pentru execuția pas cu pas putem utiliza și tasta F10. Noua valoare a unui registru sau a unei date din memorie, corespunzǎtoare instrucțiunii curente, este afișatǎ numai dupǎ apǎsarea tastei F10.

Fereastra pentru afișarea datelor apare numai dupǎ apǎsarea butonului Data. Fereastra are forma din Fig. 6

5

Page 6: Ghid utilizare QtSPIM

Fig. 6

Simultan cu deschiderea ferestrei de lucru se deschide și fereastra Console.Pentru afișarea datelor pe consolǎ se vor utiliza funcții de sistem prezentate ȋn paragraful urmǎtor.

7. Utilizarea funcțiilor sistem

Anumite funcții asemǎnǎtoare cu cele ale sistemului de operare se apeleaz cu comanda syscall introdusǎ ca orice pseudoinstrucțiune ȋn codul aplicației.

Pentru a putea utiliza aceastǎ comandǎ, ȋnǎinte de execuție este neccesar sǎ introducem ȋn registrele $a0 și $a1 argumentele funcției iar in $v0 se introduce codul funcției apelate (vezi tabelul din Fig. 7).

serviciul codul argumente rezultat print_int 1 $a0=integer print_floate 2 $f12=floate print_double 3 $f12=floate print_string 4 $a0=string read_int 5 integer in $v0 read_float 6 Float in $f0 read_double 7 Double in $f0 read_string 8 $a0=buffer, $a1=length sbrk 9 $a0=ammount exit 10

De exemplu pentru a citi un ȋntreg de la consolǎ se va utiliza serviciul (funcția) read_int cu codul 5.Pentru apelul funcției se va utiliza secvența:

li $v0, 5

6

Page 7: Ghid utilizare QtSPIM

syscall

8. Utilizarea MARS 4.4

Editarea programelor utilizator se realizeazǎ cu ajutorul unui editor propriu. Orice program care trebuie asamblat și simulat va fi ȋntȃi ȋncǎrcat ȋn editorul programului MARS.

Dupǎ activarea programului MARS (prin dublu click pi icon), pe ecran va apare o fereastrǎ ȋmpǎrțitǎ ȋn mai multe zone cu funcții specifice, ca ȋn Fig. 7.

Fig. 7Dacǎ se apasǎ butonul Execute, se va afișa fereastra din Fig. 8, ȋmpǎrțitǎ ȋn mai multe zone.

7

Page 8: Ghid utilizare QtSPIM

Fig. 8

Creare fisier nou pentru salveazǎ anuleazǎ pas cu selectie vitezǎ simulareeditare fișierul operația taie transferǎ pas pauza reset 0.05 instr/sec…maxim

deschide salveazǎ tipareste refǎ copiazǎ find/ run anuleazǎ stop help fișier cu alt fisierul replace pas pentru nume editare/ execuție

Fig. 9

Execuția ȋntregului program se lanseazǎ cu tasta F5. Execuția pas cu pas se poate realiza și cu ajutorul tastei F7. Pentru inițializarea memoriei și registrelor se apasǎ tasta F12.

MARS acceptǎ notația simbolicǎ a registrelor (vezi paragraful 5.).

8

Page 9: Ghid utilizare QtSPIM

ANEXA A

Instrucțiuni ale limbajului MIPS

1. Instrucțiuni aritmetice

add $rd, $rs, $rt - rd ←rs+rt adunare ȋn cod complementar cu generare depǎșireaddi $rt, $rs, imediat – rt ← rs+imediat adunare ȋn cod complementar cu generare depǎșireaddu $rd, $rs, $rt - rd ←rs+rt adunare ȋn cod complementar fǎrǎ generare depǎșireaddiu $rt, $rs, imediat – rt ← rs+imediat adunare ȋn cod complementar fǎrǎ generare depǎșiresub $rd, $rs, $rt - rd ←rs-rt scǎdere ȋn cod complementar cu generare depǎșiresubu $rd, $rs, $rt - rd ←rs-rt scǎdere ȋn cod complementar fǎrǎ generare depǎșiremult $rs, $rt - LO←[rs*rt]L ȋnmulțirea a douǎ numere cu semn

HO← [rs*rt]H

multu $rs, $rt - LO←¿rs*rt]L ȋnmulțirea a douǎ numere fǎrǎ semnHO← [rs*rt]H

div $rs, $rt - LO← partea ȋntreagǎ a rezultatuluiHO←restul impǎrțirii

Pseudoinstrucțiunea subi permite scǎderea imediatǎ. Sintaxa este:

subi $rt, $rs, imediat - rt ←rs-imediat scǎdere imediatǎ. Este substituitǎ de asamblor cu douǎ instrucțiuni aritmatice MIPS.

2. Instrucțiuni logice

add $rd, $rs, $rt - rd ←rs AND rt operație logicǎ AND bit cu bitandi $rt, $rs, imediat – rt ← rs+imediat operație logicǎ AND bit cu bit cu o

constantǎor $rd, $rs, $rt - rd ←rs AND rt operație logicǎ OR bit cu bitori $rt, $rs, imediat – rt ← rs OR imediat operație logicǎ OR bit cu bit cu o constantǎnor $rd, $rs, $rt - rd ←rs NOR rt operație logicǎ NOR bit cu bitxor $rd, $rs, $rt - rd ←rs XOR rt operație logicǎ XOR bit cu bit

3. Instrucțiuni de deplasare

sra $rd, $rt, sa - rd ← rt >> sa deplasare aritmeticǎ dreapta cu sa bițisrav $rd, $rt, $rs - rd ← rt >> rs deplasare aritmeticǎ dreapta cu rs bițisrl $rd, $rt, sa - rd← rt >> sa deplasare logicǎ dreapta cu sa bițisrlv $rd, $rt, $rs - rd ← rt >> rs deplasare logicǎ dreapta cu rs bițisll $rd, $rt, sa - rd ← rt << sa deplasare logicǎ stǎnga cu sa bițisllv $rd, $rt, $rs - rd ← rt << rs deplasare logicǎ stȃnga cu rs biți

sa - constantǎ fǎrǎ semn pe 5 biți (32 sa)

Obs! Deplasarea srȃnga aritmeticǎ nu este implementatǎ deoarece este identicǎ cu deplasarea stȃnga logicǎ.

9

Page 10: Ghid utilizare QtSPIM

Pe lȃngǎ instrucțiunile de deplasare prezentate mai existǎ și douǎ pseudoinstrucțiuni pentru realizarea rotirii conținutului unui registru și ȋnscrierea rezultatului ȋn alt registru specificat

ror $rd, $rt - rotire cu deplasare dreapta pe 1 bit. ror $rd, $rt - rotire cu deplasare stȃnga pe 1 bit.

Asamblorul substituie fiecare din aceste pseudoinstrucțiuni prin 3 instrucțiuni MIPS.

4. Instrucțiuni de ramificare

b eticheta - ramificare necondiționatǎbeq $rs, $rt, eticheta - ramificare dacǎ rs = rt;bne $rs, $rt, eticheta - ramificare dacǎ rs != rt;bgez $rs, eticheta - ramificare dacǎ rs 0;bgtz $rs, eticheta - ramificare dacǎ rs > 0;blez $rs, eticheta - ramificare dacǎ 0 rs;bltz $rs, eticheta - ramificare dacǎ 0 > rs;

Obs! Valoarea offset-ului este calculatǎ de cǎtre asamblor ca diferențǎ ȋntre adresa corespunzǎtoare etichetei și adresa instrucțiunii de salt + 4. Modul de prezentare a offsetului diferǎ ȋntre QtSPIM și MARS! Varianta MARS corespunde modului de execuție a instrucțiunilor de cǎtre procesor ȋn timp ce la QtSPIM se oferǎ direct valoarea ofset-ului deplasatǎ cu 2 biți spre stȃnga (ȋnmulțitǎ cu 4).

Pseudoinstrucțiunile pentru ramificare au fost prezentate ȋn paragraful 3.

5. Instrucțiuni de salt

j eticheta - salt necondiționat la adresa formatǎ prin concatenarea primilor 4 biți din PC cu indexul deplasat cu 2 biți spre stȃnga; adresa de salt este calculatǎ de asamblor.

jr $rs - salt necondiționat la adresa specificatǎ de conținutul registrului rsjal eticheta - apel la procedurǎ.; adresa de salt este calculatǎ de asamblor;

adresa de retur de salt se salveazǎ automat ȋn registrul $31 ($ra). Returul din procedurǎ se marcheazǎ prin jr $ra.

jalr $rd, $rs - apel la procedurǎ; adresa de ȋnceput a procedurii este depusǎ deja ȋn $rs;adresa de retur este salvatǎ automat ȋn $rd. Dacǎ adresa de retur este trimisǎ ȋn $31, se va utiliza forma prescurtatǎ, jalr $rs.

6. Instrucțiuni manipulare registre

mfhi $rd - copiazǎ registrul special HI ȋn registrul general $rd;mflo $rd - copiazǎ registrul special LO ȋn registrul general $rd;movn $rd, $rs, $rt - dacǎ rt<>0 , $rd ← $rs; conținutul $rt rezultǎ din execuția unei instrucțiuni

de tipul SLT, SLTI, SLTU, SLTIU.mov $rd, $rs, $rt - dacǎ rt=0 , $rd ← $rs; conținutul $rt rezultǎ din execuția unei instrucțiuni

de tipul SLT, SLTI, SLTU, SLTIU.mthi $rs - copiazǎ registrul general $rs ȋn registrul general HI;mtlo $rs - copiazǎ registrul special $rs ȋn registrul general LO;

10

Page 11: Ghid utilizare QtSPIM

11

Page 12: Ghid utilizare QtSPIM

7. Instrucțiuni lucru cu memoria

lw $rd, offset($baza) - citirea unui cuvȃnt din memorie de la adresa baza+offsetsw $rd, offset($baza) - scrierea unui cuvȃnt ȋn memorie la adresa baza+offset

12

Page 13: Ghid utilizare QtSPIM

ANEXA B

Exemple programe QtSPIM (MARS)

Fisierele test au fost create cu Notepad++ și au extensia .asm.

1. Exemplul 1

Programul test1.asm permite testarea adunǎrii respectiv scǎderii a douǎ numere cu semn introduse inițial ȋn registrele $s0 și $t0. Valorile din registre sunt ȋnscrise folosind pseudoinstrucțiunea .li.

# test1.asm# adunarea/scaderea a continutului a doua registre .text .globl main main: ori $8, $0, 25 # incarcare primul operand in registrul $8

ori $9, $0, 50 # incarcare al doilea operand in registrul $9add $17, $8, $9 # adunarea cu depunerea rezultatului in registrul $17sub $18, $8, $9 # scderea cu depunerea rezultatului in registrul $18

Asamblarea plaseazǎ codul programului utilizator ȋntotdeauna ȋncepȃnd dela adresa [00400024].Ȋn segmentul de date va apare codul atȃt ȋn limbaj de asamblare cȃt și ȋn cod hexazecimal.

[00400024] 34080019  ori $8, $0, 25           [00400028] 34090032  ori $9, $0, 50[0040002c] 01098820  add $17, $8, $9          [00400030] 01099022  sub $18, $8, $9

Ȋnǎinte de execuție registrele implicate ȋn operațiile din program au valoarea 0. Dupǎ execuție valorile registrelor vor fi:

R8  [t0] = 19R9  [t1] = 32R17 [s1] = 4bR18 [s2] = ffffffe7

Se observǎ cǎ deși operanzii din program sunt ȋn zecimal, conținutul registrelor este afișat hexa. Operațiile aritmetice au fost realizate ȋn cod complementar.

2. Exemplul 2

Programul test2.asm realizeazǎ aceleași operații ca și ȋn exemplul precedent dar al doilea operand este un numǎr ȋntreg negativ (-50).

# test2.asm# adunarea/scaderea a continutului a doua registre .text .globl main

13

Page 14: Ghid utilizare QtSPIM

main: ori $8, $0, 25 # incarcare primul operand in registrul $8

ori $9, $0, -50 # incarcare al doilea operand in registrul $9add $17, $8, $9 # adunarea cu depunerea rezultatului in registrul $17sub $18, $8, $9 # scderea cu depunerea rezultatului in registrul $18

Dupǎ ȋncǎrcarea programului va apare un mesaj ca cel din Fig. 10.

Fig. 10

Mesajul de eroare apare datoritǎ faptului cǎ un numǎr negativ se reprezintǎ ȋn cod complement fațǎ de doi și este interpretat ca un numǎr mare, adicǎ pe 32 biți și nu poate fi utilizat ca operand ȋn operații immediate. Asamblarea este opritǎ imediat.

3. Exemplul 3

Este reluat exemplul precedent dar inițializarea registrelor se realizeazǎ cu pseudoinstrucțiunile li respectiv la. Codul rezultat conține și instrucțiunile obținute prin substituire pseudoinstrucțiunilor cu instrucțiuni.

# test3.asm # adunarea/scaderea a continutului a doua registre .text .globl main main:

li $8, 25 # incarcare primul operand in registrul $8la $9, -50 # incarcare al doilea operand in registrul $9add $17, $8, $9 # adunarea cu depunerea rezultatului in registrul $17sub $18, $8, $9 # scderea cu depunerea rezultatului in registrul $18

Codul rezultat prin asamblare conține și instrucțiunile obținute prin substituire pseudoinstrucțiunilor cu instrucțiuni.

[00400024] 34080019  ori $8, $0, 25    ; 8: li $8, 25 [00400028] 3c01ffff  lui $1, -1        ; 9: la $9, -50 [0040002c] 3429ffce  ori $9, $1, -50[00400030] 01098820  add $17, $8, $9   ; 10: add $17, $8, $9 [00400034] 01099022  sub $18, $8, $9   ; 11: sub $18, $8, $9

14

Page 15: Ghid utilizare QtSPIM

4. Exemplul 4

Ȋn acest exemplu datele sunt ȋncǎrcate inițialȋn memorie cu .word iar de aici sunt citite și transferate ȋn $8, $9. Adresa de ȋnceput a blocului de memorie este ȋncǎrcatǎ la ȋnceputul programului ȋn registrul $16 cu pseudoinstrucțiunea la.

# test4.asm # adunarea/scaderea a continutului a doua registre .text .globl main main:

lui $16, 0x1001 # incarcarea adresei implicite in registrul $16lw $8, 0($16) # incarcare primul operand in registrul $8lw $9, 4($16) # incarcare al doilea operand in registrul $9add $17, $8, $9 # adunarea cu depunerea rezultatului in registrul $17sub $18, $8, $9 # scderea cu depunerea rezultatului in registrul $18

.data

.word 25, -50

Dupǎ ȋncǎrcare, ȋnǎinte de a ȋncepe execuția programului, zona de date va conține (ȋn zecimal):

User data segment [10000000]..[10040000][10000000]..[1000ffff]  00000000[10010000]    0000000025  0000000-50  0000000000  0000000000    . . . . . . . . . . . . . . . . [10010010]..[1003ffff]  00000000

Ȋn hexazecimal zona va avea forma

User data segment [10000000]..[10040000][10000000]..[1000ffff]  00000000[10010000]    00000019  ffffffce  00000000  00000000    . . . . . . . . . . . . . . . . [10010010]..[1003ffff]  00000000

Adresa de ȋnceput a ȋncǎrcǎrii datelor ȋn memorie, 0x10010000, este implicitǎ

15

Page 16: Ghid utilizare QtSPIM

5. Exemplul 5

Programul test5.asm realizeazǎ permutarea conținutului a douǎ registre.

# test5.asm # permutarea continutului a doua registre .text .globl main main:

la $20, 0x10010000 # incarcarea adresei de inceput a blocului de memorie lw $11, 0($20) # incarcare din memorie a primului registru

lw $12, 4($20) # incarcare din memorie a celui de-al doilea registruadd $13,$11,$0 # copierea primului registru in registrul tamponadd $11,$12,$0 # copierea celui de-al doilea registru in primul registru add $12,$13,$0 # copierea registrului tampon in al doilea registruadd $13,$0,$0 # stergerea registrului tampon

.data.word 234, -234

6. Exemplul 6

Programul test6.asm realizeazǎ permutarea conținutului a douǎ locații de memorie.

# test6.asm # permutarea continutului a doua locatii de memorie .text .globl main main:

la $20, 0x10010000 # incarcarea adresei de inceput a blocului de memorie lw $11, 0($20) # incarcare din memorie a primului registru

lw $12, 4($20) # incarcare din memorie a celui de-al doilea registrusw $11, 4($20) # incarcare primului registru in a doua locatiesw $12, 0($20) # incarcare a celui de-al doilea registru in prima locatie

.data.word 234, -234

7. Exemplul 7

Programul test7.asm permite copierea unui bloc de memorie ȋn altǎ zonǎ de memorie.

16

Page 17: Ghid utilizare QtSPIM

# test7.asm # copierea unui bloc de memorie .text .globl main main:

la $t9, 0x10010000 # incarcarea adresei de inceput a blocului de memorieli $t8, 15 # initializare contor

ciclu: lw $t0, 0x0($t9) # incarcare din memorie in registrul tampon

sw $t0, 0x100($t9) # transfer reg tampon in memorieaddi $t9, $t9, 4 # calcul adresa urmatoaresubi $t8, $t8, 1 # decrementare contorbgt $t8,$0 ciclu # incheiere ciclu

.data.word 1, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

Ȋn urma asamblǎrii cu programul MARS rezultǎ:

Fig. 11

Contorul $t8 ($24) conține numǎrul de elemente din lista (vectorul, tabelul) transferatǎ. Pentru exemplul considerate sunt 15 numere.

Adresa inițialǎ a listei copiat este chiar ȋnceputul segmentului de date 0x10010000 iar adresa de ȋnceput a noii locații este 0x1001100.

La fiecare pas adresa locației se incrementeazǎ cu 4. Pentru testarea terminǎrii execuției se utilizeazǎ pseudoinstrucțiunea de ramificare bgt, translatatǎ de

asamblor ȋn douǎ instrucțiuni (slt și bne) cum s-a arǎtat ȋn paragraful 3.

8. Exemplul 8

Programul test8.asm permite adunarea a doi vectori a cȃte 20 numere ȋntregi fiecare și plasarea rezultatului ȋn locul celui de-al doilea vector. Vectorii sunt plasați ȋn zone de memorie contigue.

17

Page 18: Ghid utilizare QtSPIM

# test8.asm

# adunarea a doi vectori de numere intregi

# rezultatul este depus in locul celui de-al doilea vector

.text

.globl main

main: la $t8, 0x10010000 # incarcarea adresei de inceput a blocului de memorie li $t9, 20 # initializare contor - numar elemente vector ciclu: lw $t0, 0($t8) # citirea primului vector lw $t1, 80($t8) # citirea celui de-al doilea vector add $s0, $t0, $t1 # calculul sumei a doua elemente sw $s0, 80($t8) # salvarea rezultatului addi $t8, $t8, 4 # calcul adresa celulei urmatoare subi $t9, $t9, 1 # decrementare contor bgt $t9, $zero, ciclu # testare sfarsit ciclu .data

.word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

.word 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119

Ultimile douǎ linii reprezintǎ pseudoinstrucțiuni. Ȋn urma asamblǎrii rezultǎ secvența de cod din Fig. 12. Se observǎ cǎ fiecǎrei pseudoinstrucțiuni ȋi corespund douǎ instrucțiuni.

Fig. 12

9. Exemplul 9

Programul test10.asm permite afișarea unui mesaj inscris ȋntr-un bloc al memoriei RAM. Mesajul a fost ȋnscris ȋn memorie cu directiva .asciiz . Șirul va fi terminat automat cu zero.

Directiva .space rezervǎ un bloc de memorie cu capacitatea 16 octeți.Eticheta mesaj reprezintǎ adresa ȋnceputului mesajului ȋn memorie.

# test10.asm# Hello World

.data # segment declarare date

18

Page 19: Ghid utilizare QtSPIM

.space 16 # rezervare spatiu de 16 biti memorie RAMmesaj: .asciiz "Hello World \n"

.text # segment pentru program utilizator main: li $v0,4 # incarcare cod syscall (print_string) la $a0, mesaj # incarcare argument syscall (adresa de inceput bloc memorie cu mesaj afisat) syscall # afisare mesaj li $v0,10 # incarcare cod syscall (exit) syscall # iesire program

10. Exemplul 10

Programul test9.asm permite adunarea a doi operanzi ȋntregi. Cei doi operanzi sunt citiți de la consolǎ iar suma este afișatǎ la consolǎ.

Fiecare operand se introduce de la tastatura si se termina cu ENTER.

.text

.globl mainmain:

la $a0, op1 # incarca adresa mesajului A=li $v0, 4 # incarca cod print_stringsyscall # afiseaza A=li $v0, 5 # incarca cod read_intsyscall # citeste operandul 1 in $v0move $t0, $v0 # salveaza operandul 1la $a0, op2 # incarca adresa mesajului B=li $v0, 4 # incarca cod print_stringsyscall # afiseaza B=li $v0, 5 # incarca cod read_intsyscall # citeste operandul 2 in $v0move $t1, $v0 # salveaza operandul 2la $a0, suma # incarca adresa mesajului A+B=li $v0, 4 # incarca cod print_stringsyscall # afiseaza A+B=add $a0,$t0,$t1 # calcul suma

li $v0, 1 # incarca cod print_intsyscall # tipareste suma din $a0li $v0, 10 # incarca cod exitsyscall # exit

.data op1: .asciiz "\nA="op2: .asciiz "\nB="suma:.asciiz "\nA+B="

Consola va arata in final ca ȋn Fig. 13.

19

Page 20: Ghid utilizare QtSPIM

Fig. 13

11. Exemplul 11

Programul test11.asm permite determinarea valorilor minimǎ și maximǎ dintr-un șir de n numere ȋntregi. Valorile determinate sunt afișate la consolǎ.

# test11.asm# determinarea valorilor minima si maxima # dintr-un vector de n numere reale.data baza_vector: .word -10,-20,100,128,120,-30,35,121,-35,15

minim: .asciiz "valoarea minima = "maxim: .asciiz "\nvaloare maxima="

.text # segmentul de instructiuni ale aplicatiei

.globl main

main: # $t0 registrul tampon baza # $t1 valoare minima # $t2 valoare maxima # $t3 registru tampon numere # $t4 contor ciclare # $s1 numar elemente n # $s0 adresa baza vecor li $s1, 10 # incarcare valoare n (numar elemente vector) la $s0, baza_vector # incarcare adresa primul element vector move $t0, $s0 # initializare tampon adresa move $t4, $s1 # initializare contor ciclare lw $t1, 0($t0) # initializare valoare minima cu primul element din vector lw $t2, 0($t0) # initializare valoare minima cu primul element din vector addiu $t0,$t0,4 # incrementare baza addi $t4, $t4, -1 # decrementare contor ciclu: lw $t3, 0($t0) # incarca urmatorul numar din vector ble $t1, $t3, et1 # compara cu valoarea minima move $t1, $t3 # incarca noua valoare minima et1: bge $t2, $t3, et2 # compara cu valoarea maxima move $t2, $t3 # incarca noua valoare maxima

20

Page 21: Ghid utilizare QtSPIM

et2: addiu $t0,$t0,4 # calcul adresa urmatorului numar addi $t4, $t4, -1 # decrementare contor bgt $t4, $zero, ciclu # daca contorul este diferit de 0 se reia cautarea afisare: li $v0, 4 # incarca cod print_string la $a0, minim # incarca adresa mesaj minim syscall # afiseaza mesaj minim li $v0, 1 # incarca cod print_int move $a0, $t1 # initializare argument functie syscall # tiparire valoare minima li $v0, 4 # incarca cod print_string la $a0, maxim # incarca adresa mesaj maxim syscall # afiseaza mesaj maxim li $v0, 1 # incarca cod print_int move $a0, $t2 # initializare argument functie syscall # tiparire valoare maxima li $v0, 10 # incarca cod exit syscall # exit

Dupǎ asamblare se obține:

Fig. 13Rezultatul execuției este afișat ca ȋn Fig. 14.

21

Page 22: Ghid utilizare QtSPIM

Fig. 14

12. Exemplul 12

Programul test12.asm are ca scop ordonarea descrescǎtoare a valorilor unui vector depus initial In memoria de date ȋncepȃnd cu adresa vectorn. Toate valorile vectorului sunt de tip word. Vectorul sortat este depus in memorie ȋncepȃnd cu adresa vectors.

Prima etapǎ a programului copiazǎ vectorul initial ȋn zona rezervatǎ vectorului sortat. Toate operațiile necesare sortǎrii vor fi realizate pe aceastǎ copie.

A doua etapǎ constǎ ȋn sortarea descrescǎtoare. Pentru aceasta a fost ales un algoritm neperformant dar ușor de ȋnțeles și de implementat. Pașii algoritmului sunt reprezentați ȋn diagrama din Fig. 15 iar programul MIPS implementat pe baza acestui algoritm este afișat ȋn Fig. 16.

Ȋn ultima etapǎ sunt afișați cei doi vector (nesortat și sortat).Rezultatul execuției este oferit ȋn Fig. 17.

Fig. 15

22

Page 23: Ghid utilizare QtSPIM

# test12# ordonarea descrescatoare a valorilor unui vector de numere intregi

.text

main: # $t0 - element1 # $t1 - element2 # $t2 - registrul tampon # $t3 - contor ciclare 1 (i) # $t4 - contor ciclare 2 (k) # $t5 - adresa element 1 # $t6 - adresa element 2 # $t7 lungimea vectorului (n) # $t8 adresa primului element din vector nesortat # $t9 adresa primului element din vector sortat

# copiere vector nesortat in # zona rezervata vectorului sortat

li $t7, 5 # initializare lungime vector la $t8, vectorn # initializare adresa primului element din vector nesortat la $t9, vectors # initializare adresa primului element din vector sortat move $t3, $t7 # initializare contor 1 move $t5, $t8 # initializare adresa 1 move $t6, $t9 # initializare adresa 2copiat: lw $t2, ($t5) # citire element i sw $t2, ($t6) # copiere element i in vectorul sortat addiu $t5, $t5, 4 # calcul adresa urmatoarului element de transferat addiu $t6, $t6, 4 # calcul adresa urmatoare element transferat subiu $t3, $t3, 1 # decrementare contor bnez $t3, copiat #verificare sfarsit ciclare

# aplicare algoritm sortare

li $t3, 1 # initializare contor i move $t5, $t9 # initializare adresa 1 ciclul1: addi $t4, $t3, 1 # initializare contor k addiu $t6, $t5, 4 # initializare adresa 2

ciclul2: lw $t0, ($t5) # citire element i lw $t1, ($t6) # citire element k bgt $t0, $t1, salt # comparare v(i) cu v(k) sw $t1, ($t5) # permutare element i sw $t0, ($t6) # cu element k salt: addi $t4, $t4, 1 # decrementare contor k addiu $t6, $t6, 4 # calcul noua dresa v(k) ble $t4, $t7 ciclul2 # verificare sfarsit ciclul 2 addi $t3, $t3, 1 # decrementare contor i addiu $t5, $t5, 4 # calcul noua dresa v(k) blt $t3, $t7, ciclul1 # verificare sfarsit ciclu 1

23

Page 24: Ghid utilizare QtSPIM

# afisarea rezultatului

# afisare vector initial li $v0, 4 # incarca cod print_string la $a0, titlul1 # incarca adresa primului mesaj syscall # afiseaza primul mesaj move $t2, $t7 # initializare contor ciclu tiparire vector neordonat move $t5, $t8 # initializare argument functieafisare1: li $v0, 1 # incarca cod print_int lw $a0, ($t5) # incarca element vector nesortat syscall # tiparire valoare citita li $v0, 4 # incarca cod print_string la $a0, separator # incarca adresa separator syscall # tiparire separator subi $t2, $t2, 1 # decrementare contor addi $t5, $t5, 4 # calculul adresei urmatorului element bnez $t2, afisare1 # testare sfarsit ciclu # afisare vector sortat li $v0, 4 # incarca cod print_string la $a0, titlul2 # incarca adresa al doilea mesaj syscall # afiseaza al doilea mesaj move $t2, $t7 # initializare contor ciclu tiparire vector neordonat move $t6, $t9 # initializare argument functieafisare2: li $v0, 1 # incarca cod print_int lw $a0, ($t6) # incarca element vector sortat syscall # tiparire valoare citita li $v0, 4 # incarca cod print_string la $a0, separator # incarca adresa separator syscall # tiparire separator subi $t2, $t2, 1 # decrementare contor addi $t6, $t6, 4 # calculul adresei urmatorului element bnez $t2, afisare2 # testare sfarsit ciclu li $v0, 10 # incarcare cod exitsyscall # apel functie exit

.data

vectorn: .word 5,20,3,7,12 # vector nesortatvectors: .space 100 # vector sortat

titlul1: .asciiz "vector neordonat\n "titlul2: .asciiz "vector sortat descrescator\n"separator: .asciiz "\n"

Fig. 16

24

Page 25: Ghid utilizare QtSPIM

Fig. 17

Observație! Considerați ca date de test vectorul

.word -5,299999999999999999999999999999999999999999999999999,3,0,12

Analizați rezultatul și explicați-l.

13. Exemplul 13

Programul test11.asm oferǎ cȃteva exemple de execuție a unor instrucțiuni și pseudo-instrucțiuni pentru realizarea unor operații de deplasare/rotire logice și aritmetice. Se prezintǎ exemple atȃt pentru operații cu distanțǎ de deplasare rotire fixǎ cȃt și variabilǎ. Programul este prezentat ȋn continuare. Se recomandǎ execuția pas cu pas pentru a ȋnțelege mai bine semnificația rezultatelor obținute.

# test13.asm# operatii de deplasare si rotire a continutului unui registru

.text main

main: # $t0 - registru care contine valoarea initiala # $t1 - registrul care contine rezultatul operatiilor de deplasare si rotire # $t2 - contine distanta deplasarii/rotirii pentru operatii cu lungime variabila li $t0, 0x3fffabdc # incarcare valoare initiala li $v0, 1 # incarcare cod operatie print intiger move $a0, $t0 # copiaza valoarea initiala in argumentul functiei syscall # tipareste valoarea initiala li $v0, 4 # incarcare cod operatie print string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator li $t2, 3 # initializarea distantei de deplasare/rotire # exemple deplasare logica/aritmetica stanga/dreapta # exemplul 1 srl $t1, $t0, 2 # deplasare logica dreapta cu 2 biti

25

Page 26: Ghid utilizare QtSPIM

li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat li $v0, 4 # incarcare cod operatie print_string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # exemplul 2 sllv $t1, $t1, $t2 # deplasare logica stanga cu 3 biti li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat li $v0, 4 # incarcare cod operatie print string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # exemplul 3 sll $t1, $t1, 2 # deplasare logica stanga cu 2 biti li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat li $v0, 4 # incarcare cod operatie print string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # exemplul 4 sra $t1, $t1, 3 # deplasare aritmetica dreapta cu 3 biti li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat li $v0, 4 # incarcare cod operatie print string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # exemplul 5 srl $t1, $t1, 2 # deplasare aritmetica dreapta cu 3 biti li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat li $v0, 4 # incarcare cod operatie print string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # operatii de rotire stanga/dreapta # exemplul 1 rol $t1, $t0, 2 # rotire dreapta cu 2 biti li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat li $v0, 4 # incarcare cod operatie print_string la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # exemplul 2 ror $t1, $t1, $t2 # rotire stanga cu 3 biti li $v0, 1 # incarcare cod operatie print_int move $a0, $t1 # copiaza valoarea rezultat in argumentul functiei syscall # tipareste valoarea rezultat

26

Page 27: Ghid utilizare QtSPIM

li $v0, 4 # incarcare cod operatie print string

la $a0, terminator # copiaza valoarea terminator in argumentul functiei syscall # tipareste terminator # incheiere program li $v0, 10 # incarcare cod exit syscall # exit .data

terminator: .asciiz "\n"

14. Exemplul 14

Programul test14.asm oferǎ douǎ exemple de operații aritmetice realizate cu numere ȋntregi. Rezultatele sunt inițial depuse ȋn registrele speciale hi și lo.

La ȋnmulțire ȋn registrul lo se depune iar ȋn registrul hi se depuneLa ȋmpǎrțire ȋn registrul lo se depune cȃtul iar ȋn registrul hi se depune restul.

.text

.globl main

main: li $t0, -20 # valoare valoare inmultitor/impartitor li $t1, 0x000000fa # 250 - valoare deinmultit/deimpartit

# exemplul 1 mult $t0, $t1 # calcul produs t0*t1 mfhi $a0 # transfer registru hi li $v0, 1 # transfera cod print_int syscall # tipareste la consola li $v0, 4 # transfera cod print_string la $a0, separator # incarca adresa separator syscall # tipareste la consola separator mflo $a0 # transfer registru lo li $v0, 1 # transfera cod print_int syscall # tipareste la consola li $v0, 4 # transfera cod print_string la $a0, separator # incarca adresa separator syscall # tipareste la consola separator

# exemplul 2 div $t1, $t0 # calcul produs t0*t1 mflo $a0 # transfer registru lo li $v0, 1 # transfera cod print_int syscall # tipareste la consola li $v0, 4 # transfera cod print_string la $a0, separator # incarca adresa separator syscall # tipareste la consola separator mfhi $a0 # transfer registru hi li $v0, 1 # transfera cod print_int syscall # tipareste la consola

27

Page 28: Ghid utilizare QtSPIM

li $v0, 4 # transfera cod print_string la $a0, separator # incarca adresa separator syscall # tipareste la consola separator # sfarsit program li $v0, 10 # incarca codul exit syscall # exit .data separator: .asciiz " \n" # CR

15. Exemplul 15

16.

28