ELEMANIA
Z80 - Parametri e valore di ritorno
Passaggio di parametri e valore di ritorno

Per poter eseguire i propri calcoli una subroutine deve ricevere un certo numero di valori dal chiamante (parametri); in modo analogo essa deve fornire un risultato (valore di ritorno) al chiamante. Mediante parametri e valore di ritorno una subroutine è in sostanza in grado di comunicare col chiamante. Un esempio tratto dal linguaggio C è il seguente:

risultato = somma(num1, num2);

La funzione somma riceve i valori di num1 e di num2 dal chiamante, esegue la somma e restituisce un valore di ritorno che viene salvato in risultato.

In assembly non esiste nessun meccanismo automatico per realizzare questo passaggio: è compito del programmatore implementarlo. Un modo semplice è quello di utilizzare dei registri del µP per inviare e ricevere valori dalla subroutine. Questa soluzione (usata in tutti i nostri precedenti esempi) è molto facile da realizzare ma presenta alcuni inconvenienti:

Il primo problema può essere facilmente risolto usando locazioni di memoria, invece di registri, per salvare i dati da passare da e verso la subroutine. Il secondo problema è invece più grave, in particolare nel caso di programmi complessi, con molte subroutine che si chiamano reciprocamente.

Una soluzione più elegante è quella di usare lo stack anche per il passaggio dei parametri e per la ricezione del valore di ritorno dalla subroutine. A questo proposito sono due le tecniche e le convenzioni maggiormente usate:

Entrambe le tecniche presentano pro e contro che non possiamo discutere approfonditamente in questa sede.

Usando la convenzione standard, la chiamata alla funzione avviene in questo modo:

PUSH BC           ; salva i parametri (es. B e C) sullo stack
CALL subroutine ; chiama la subroutine
POP AF             ; recupera dallo stack il valore del risultato

All'interno della subroutine il meccanismo è questo:

subroutine:
POP DE ; estrae l'indirizzo di ritorno dallo stack
POP BC ; estrae dallo stack i parametri
PUSH DE ; ripristina l'indirizzo di ritorno sullo stack

Si osservi che la subroutine deve prima estrarre dallo stack l'indirizzo di ritorno (salvato al momento della CALL) in modo da poter accedere ai parametri sottostanti. Infine la subroutine deve ripristinare sullo stack tale valore.

Analogamente prima dell'istruzione RET bisogna eseguire

POP DE ; estrae l'indirizzo di ritorno
PUSH AF ; mette sullo stack il risultato
PUSH DE ; ripristina l'indirizzo di ritorno
RET

Come esempio di chiamata di subroutine secondo la convenzione C osserviamo lo schema seguente:

            PUSH DE    ; questa istruzione serve solo per lasciare uno spazio in cima allo stack
                            ; in tale spazio la funzione salverà il suo valore di ritorno
                            ; al posto di DE è possibile scrivere qualsiasi cosa

             PUSH BC    ; salva i parametri BC sullo stack

             CALL subroutine    ; chiama la subroutine
 
             POP BC    ; ripulisce lo stack dai parametri
                           ; (al posto di BC si può usare qualsiasi coppia di registri)

             POP DE    ; preleva il valore di ritorno dallo stack

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it