Procedure

Le procedure sono delle porzioni di codice associate ad un nome, che possono essere invocate più volte e che eseguono un compito specifico. Hanno una lista di parametri come input e come output un valore di ritorno.

Vantaggi:

  • Astrazione
  • Riusabilità del codice
  • Maggiore organizzazione del codice
  • Testing più agevole

Un esempio sono le funzioni di C:

...
f = f + 1;
risultato = somma(f, g);

La procedura chiamante sopra, invoca un'altra procedura (chiamata):

int somma(f, g){
	return f + g + 2;
}

Procedura, passi da seguire:
...

Chiamante

  • Mettere i parametri in un luogo accessibile alla procedure
  • Trasferire il controllo alla procedura

Chiamato

  • Acquisire le risorse necessarie per l'esecuzione della procedura
  • Eseguire il compito richiesto
  • Mettere il risultato in un luogo accessibile al programma chiamante
  • Restituire il controllo al punto di origine
    (la stessa procedura può essere chiamata in punti differenti di un programma)

Modifica del flusso di un programma: invocazione
...

jal IndirizzoProcedura
jal = jump and link

Salta all'indirizzo (offset) con etichetta IndirizzoProcedura.
Una volta che è stata eseguita la procedura invocata, il PC esegue il codice a partire dall'istruzione successiva al punto in cui è stata chiamata la procedura. L'indirizzo dell'istruzione successiva (del PC) viene memorizzata nel registro x1 (return address ra) per potervi ritornare alla fine della procedura. L'istruzione successiva sarà PC + 4.

JAL e linguaggio macchina
...

Viene introdotto un nuovo formato di istruzione: J
Pasted image 20230330104912.png

Ritorno al chiamante
...

jalr rd, offset(rs1)
jalr = jump and link register

Questa istruzione consente al PC di saltare ad un indirizzo qualsiasi.
Quando la procedura che è stata chiamata ha finito di eseguire il suo corpo, come ultima cosa deve ritornare al punto in cui la procedura è stata chiamata (nel chiamante). Questo viene fatto grazie a questa istruzione, in particolare:
jalr x0, 0(x1)
(jalr è codificata con il formato di istruzione del tipo I), x1 come abbiamo già detto è l'indirizzo dell'istruzione successiva.

Effetti collaterali
...

Questa istruzione, per come è implementate si porta dietro una serie di problemi:

Queste tre soluzioni hanno una cosa in comune, l'utilizzo della memoria come strumento di appoggio per salvare il valore di eventuali valori di ritorno, o di contenuti di registri che potrebbero essere utilizzati nella funzione chiamata o del numero eccessivo di parametri e/o variabili utilizzate da un procedura. L'area di memoria in cui è possibile salvare i registri per evitarne la perdita è lo stack.

Oltre allo stack, in memoria trovano posto:

  • dati allocati dinamicamente (ad esempio attraverso la funzione malloc() del C)
  • dati statici e variabili globali
  • codice del programma
    Lo stack e i dati dinamici crescono in direzioni differenti, in modo da ottimizzarne la gestione.
    Pasted image 20230411101612.png

Esempi di codice assembly RISC-V: