Il comportamento dello stack (in crescita o in diminuzione) dipende dall'interfaccia binaria dell'applicazione (ABI) e da come è organizzato lo stack di chiamate (noto anche come record di attivazione).
Per tutta la sua vita un programma è destinato a comunicare con altri programmi come OS. ABI determina come un programma può comunicare con un altro programma.
Lo stack per architetture diverse può crescere in entrambi i modi, ma per un'architettura sarà coerente. Si prega di controllare questo collegamento wiki. Ma la crescita dello stack è decisa dall'ABI di quell'architettura.
Ad esempio, se prendi l'ABI MIPS, lo stack di chiamate è definito come di seguito.
Consideriamo che la funzione "fn1" chiama "fn2". Ora lo stack frame visto da 'fn2' è il seguente:
direction of | |
growth of +---------------------------------+
stack | Parameters passed by fn1(caller)|
from higher addr.| |
to lower addr. | Direction of growth is opposite |
| | to direction of stack growth |
| +---------------------------------+ <-- SP on entry to fn2
| | Return address from fn2(callee) |
V +---------------------------------+
| Callee saved registers being |
| used in the callee function |
+---------------------------------+
| Local variables of fn2 |
|(Direction of growth of frame is |
| same as direction of growth of |
| stack) |
+---------------------------------+
| Arguments to functions called |
| by fn2 |
+---------------------------------+ <- Current SP after stack
frame is allocated
Ora puoi vedere che lo stack cresce verso il basso. Quindi, se le variabili sono allocate al frame locale della funzione, gli indirizzi della variabile aumentano effettivamente verso il basso. Il compilatore può decidere l'ordine delle variabili per l'allocazione della memoria. (Nel tuo caso può essere "q" o "s" la prima memoria di stack allocata. Ma, generalmente il compilatore esegue l'allocazione di memoria di stack secondo l'ordine della dichiarazione delle variabili).
Ma nel caso degli array, l'allocazione ha un solo puntatore e la memoria da allocare sarà effettivamente puntata da un singolo puntatore. La memoria deve essere contigua per un array. Quindi, sebbene lo stack cresca verso il basso, per gli array lo stack cresce.