28
(1) Procedure in assembler

Procedure in assembler

  • Upload
    rhea

  • View
    41

  • Download
    1

Embed Size (px)

DESCRIPTION

Procedure in assembler. Procedure. Una procedura, o subrutine, è uno strumento che i programmatori usano per strutturare i programmi, sia per renderli più facili da capire che per permettere il riutilizzo del codice. - PowerPoint PPT Presentation

Citation preview

Page 1: Procedure in assembler

(1)

Procedure in assembler

Page 2: Procedure in assembler

(2)

Procedure

Una procedura, o subrutine, è uno strumento che i programmatori usano per strutturare i programmi, sia per renderli più facili da capire che per permettere il riutilizzo del codice.Le procedure consentono di concentrarsi su una parte del problema, i parametri permettono di scambiare dati.

Page 3: Procedure in assembler

(3)

Procedure° I registri giocano un ruolo importante per tenere traccia delle procedure e memorizzare i valori di ritorno.

°Convenzioni:• Indirizzo di ritorno $ra

• Passaggio dei parametri $a0, $a1, $a2, $a3

• Valori di ritorno $v0, $v1

• Variabili locali $s0, $s1, … , $s7

Page 4: Procedure in assembler

(4)

Proceduremain() {int i,j,k,m;

i = mult(j,k); ... m = mult(i,i); ...

}

/* really dumb mult function */

int mult (int mcand, int mlier){int product;

product = 0;while (mlier > 0) { product = product + mcand; mlier = mlier -1; }return product;}

Page 5: Procedure in assembler

(5)

Istruzioni per procedure (1/4) ... sum(a,b);... /* a,b:$s0,$s1 */}int sum(int x, int y) { return x+y;}

address1000 add $a0,$s0,$zero # x = a1004 add $a1,$s1,$zero # y = b 1008 addi $ra,$zero,1016 #$ra=10161012 j sum #jump to sum1016 ...

2000 sum: add $v0,$a0,$a12004 jr $ra # new instruction

HLL

MIPS

Page 6: Procedure in assembler

(6)

Istruzioni per procedure (2/4)°Esiste una istruzione singola che salta ad un indirizzo e contemporaneamente salva l’indirizzo dell’istruzione successiva nel registro $ra : jump and link (jal)

°Prima:

1008 addi $ra,$zero,1016 #$ra=10161012 j sum #go to sum

°Dopo:

1012 jal sum # $ra=1016,go to sum

Page 7: Procedure in assembler

(7)

Istruzioni per procedure (3/4)°La sintassi per jal (jump and link) è la stessa di j (jump):

jal label

° jal dovrebbe essere chiamato laj : “link and jump”:•Step 1 (link): Salva l’indirizzo dell’isruzione che segue in $ra

•Step 2 (jump): Salta all’etichetta indicata

Page 8: Procedure in assembler

(8)

Istruzioni per procedure (4/4)°La sintassi per jr (jump register):

jr register

° Invece di prevedere un etichetta alla quale saltare, l’istruzione jr prevede un registro che contiene un indirizzo.

•jal memorizza l’indirizzo di ritorno nel registro ($ra)•jr ritorna a quell’indirizzo

Page 9: Procedure in assembler

(9)

Nested Procedures (1/2)int sumSquare(int x, int y) {

return mult(x,x)+ y;}

°Qualcuno ha chiamato sumSquare, ora sumSquare sta chiamando mult.

°Così c’è un valore in $ra al quale sumSquare vuole ritornare, ma sarà sovrascritto dalla chiamata a mult.

°Bisogna salvare l’indirizzo di ritorno sumSquare prima di chiamare mult.

Page 10: Procedure in assembler

(10)

Nested Procedures (2/2)° In generale può esserci il bisogno di salvare qualche altra informazione oltre che quelle in $ra.

°Quando un programma gira, sono allocate tre importanti aree della memoria:•Static: variabili dichiarate nel programma una volta per tutte, finiscono di esistere solo quando il programma termina. E.g., globali•Heap: variabili dichiarate dinamicamente•Stack (pila): Spazio utilizzato dalle procedure durante l’esecuzione: dove è possibile salvare I valori dei registri

Page 11: Procedure in assembler

(11)

HLL memory Allocation

0

Indirizzi

Code Programma

Static Variabili globali

HeapSpazio creato esplicitamente, e.g., puntatori

StackSpazio per le procedure

$sp puntatore

stack

Page 12: Procedure in assembler

(12)

Usare la Stack (1/2)°La stack è una coda del tipo last-in first-out

(l’ultimo ad entrare è il primo ad uscire)

°Abbiamo un registro $sp che punta sempre all’ultimo spazio usato nella stack dove la procedura può memorizzare I registri da riversare e dove può recuperare I vecchi valori dei registri.

° Il puntatore dello stack viene aggiornato ogni volta che viene inserito o estratto il valore di un registro.

°Lo stack “cresce” a partire da indirizzi di memoria alti verso indirizzi di memoria bassi.

Page 13: Procedure in assembler

(13)

Usare la Stack (2/2)

sumSquare: addi $sp,$sp,-8 # space on stack sw $ra, 4($sp) # save ret addr sw $a1, 0($sp) # save y

add $a1,$a0,$zero # mult(x,x) jal mult # call mult

lw $a1, 0($sp) # restore y add $v0,$v0,$a1 # mult()+y lw $ra, 4($sp) # get ret addr addi $sp,$sp,8 # restore stack

jr $ramult: ...

int sumSquare(int x, int y) {return mult(x,x)+ y; }

“push”Memorizzareun dato

“pop”Estrarre un dato

Page 14: Procedure in assembler

(14)

Passi per una chiamata di procedura1) Salvare I valori necessari nella stack.

2) Assegnare gli argomenti, se ce ne sono.

3) jal

4) Riprendere i valori dalla stack.

Page 15: Procedure in assembler

(15)

Regole per le procedure°Vengono chiamate con un istruzione jal, ritornano al punto chiamante con jr $ra

°Accettano fino a 4 argomenti $a0, $a1, $a2 e $a3

° Il valore di ritorno è sempre in $v0 (e se necessario in $v1)

°Devono seguire le convenzioni per I registri

Page 16: Procedure in assembler

(16)

Registri MIPS

The constant 0 $0 $zeroReserved for Assembler $1 $atReturn Values $2-$3 $v0-$v1Arguments $4-$7 $a0-$a3Temporary $8-$15 $t0-$t7Saved $16-$23 $s0-$s7More Temporary $24-$25 $t8-$t9Used by Kernel $26-27 $k0-$k1Global Pointer $28 $gpStack Pointer $29 $spFrame Pointer $30 $fpReturn Address $31 $ra

Usare nomi per I registri – il codice è più chiaro!

Page 17: Procedure in assembler

(17)

Convenzioni per i registri (1/5)°Caller: La procedura chiamante

°Callee: La procedura chiamata

°Quando callee ritorna dall’esecuzione, caller deve sapere quali registri può aver cambiato e quali sono sicuramente rimasti invariati.

°Register Conventions: Un insieme di regole generalmente accettate a proposito di quali registri una chiamata ad una procedura può (e non può cambiare).

Page 18: Procedure in assembler

(18)

Convenzioni per i registri (2/5)°$0: No Change. Sempre 0.

°$s0-$s7: No Change. Se callee cambia questi valori ci deve rimettere I valori originali prima di ritornare.

°$sp: No Change. Il puntatore alla stack deve essere lo stesso prima e dopo la chiamata jal.

Page 19: Procedure in assembler

(19)

Convenzioni per i registri (3/5)°$ra: Change. jal stesso cambierà questo

registro. Caller ha bisogno di salvarlo nella stack se c’è un’altra chiamata.

°$v0-$v1: Change. Aspettano I nuovi valori.

°$a0-$a3: Change. Sono gli argomenti. Caller deve salvarli se ha ancora bisogno di loro dopo la chiamata.

°$t0-$t9: Change. Sono chiamati temporanei: ogni procedura può cambiarli in ogni momento. Caller deve salvarli se ha ancora bisogno di loro dopo la chiamata.

Page 20: Procedure in assembler

(20)

Convenzioni per i registri (4/5)°Cosa significa?•Se la procedura R chiama la procedura E, allora R deve salvare ogni registro temporaneo che può usare nella stack prima di un jal .

• La procedura E deve salvare ogni S registro che intende usare prima di recuperare I suoi valori.

•Ricordate: Caller/callee hanno bisogno di salvare solo I registri di cui hanno bisogno.

Page 21: Procedure in assembler

(21)

Convenzioni per i registri (5/5)°Notate che se callee è arrivato ad usare qualche registro s deve:•Salvare s nella stack•Usare I registri•Riprendere s dalla stack•jr $ra

Page 22: Procedure in assembler

(22)

“In conclusione…” (1/2)°Le procedure sono chiamate con jal, e ritornano con jr $ra.

°Usate la stack per salvare tutto quello di cui avete bisogno.

°Register Conventions: Usatele!.

Page 23: Procedure in assembler

(23)

“In conclusione…” (2/2)° Istruzioni che conosciamo

Arithmetic: add, addi, sub, addu, addiu, subu

Memory: lw, sw

Decision: beq, bne, slt, slti, sltu, sltiu

Unconditional Branches (Jumps):j, jal, jr

Page 24: Procedure in assembler

(24)

Esempio (1/5)main()

{int i,j,k,m; /* i-m:$s0-$s3 */

i = mult(j,k); ... m = mult(i,i); ...

}

int mult (int mcand, int mlier){int product;

product = 0;while (mlier > 0) { product += mcand; mlier -= 1; }return product;}

Page 25: Procedure in assembler

(25)

Esempio (2/5)__start:

add $a0,$s1,$0 # arg0 = jadd $a1,$s2,$0 # arg1 = k jal mult # call multadd $s0,$v0,$0 # i = mult()... add $a0,$s0,$0 # arg0 = iadd $a1,$s0,$0 # arg1 = i jal mult # call multadd $s3,$v0,$0 # m = mult()...

done

Page 26: Procedure in assembler

(26)

Esempio (3/5)°Note:• La funzione main finisce con done e non con jr $ra: non c’è bisogno di salvare $ra nella stack

Page 27: Procedure in assembler

(27)

Esempio (4/5)mult:

add $t0,$0,$0 # prod=0Loop:

slt $t1,$0,$a1 # mlr > 0?

beq $t1,$0,Fin # no=>Fin add $t0,$t0,$a0 # prod+=mc addi $a1,$a1,-1 # mlr-=1 j Loop # goto LoopFin:

add $v0,$t0,$0 # $v0=prod jr $ra #

return

Page 28: Procedure in assembler

(28)

Esempio (5/5)°Note:•Non vengono fatti jal da mult e non usiamo registri salvati: non abbiamo bisogno di mettere qualcosa da ricordare nella stack.

• $a1 è direttamente modificato

• Il risultato è messo in $v0