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
(1)
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.
(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
(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;}
(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
(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
(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
(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
(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.
(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
(11)
HLL memory Allocation
0
Indirizzi
Code Programma
Static Variabili globali
HeapSpazio creato esplicitamente, e.g., puntatori
StackSpazio per le procedure
$sp puntatore
stack
(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.
(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
(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.
(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
(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!
(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).
(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.
(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.
(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.
(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
(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!.
(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
(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;}
(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
(26)
Esempio (3/5)°Note:• La funzione main finisce con done e non con jr $ra: non c’è bisogno di salvare $ra nella stack
(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
(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