Registro dello stack - Stack register
Uno stack register è un registro del processore centrale del computer il cui scopo è tenere traccia di uno stack di chiamate . Su una macchina con architettura basata su accumulatori , questo potrebbe essere un registro dedicato come SP su una macchina Intel x86 . Su una macchina a registro generale , può essere un registro riservato per convenzione, come sulle macchine PDP-11 o RISC . Alcuni progetti come Data General Eclipse non avevano un registro dedicato, ma utilizzavano un indirizzo di memoria hardware riservato per questa funzione.
Le macchine prima della fine degli anni '60, come il PDP-8 e l' HP 2100, non avevano compilatori che supportassero la ricorsione . Le loro istruzioni di subroutine in genere salvano la posizione corrente nell'indirizzo di salto e quindi impostavano il contatore del programma all'indirizzo successivo . Anche se questo è più semplice che mantenere uno stack, poiché c'è solo una posizione di ritorno per sezione di codice di subroutine, non può esserci ricorsione senza uno sforzo considerevole da parte del programmatore.
Una macchina dello stack ha 2 o più registri dello stack: uno di loro tiene traccia di uno stack di chiamate , l'altro (i) tiene traccia degli altri stack .
Registri di stack in x86
In 8086 , il registro dello stack principale è chiamato stack pointer - SP. Lo stack segment register (SS) viene solitamente utilizzato per memorizzare le informazioni sul segmento di memoria che memorizza lo stack di chiamate del programma attualmente eseguito. SP punta alla cima dello stack corrente. Per impostazione predefinita, lo stack cresce verso il basso nella memoria, quindi i valori più recenti vengono inseriti negli indirizzi di memoria inferiori. Per inserire un valore nello stack, PUSHviene utilizzata l' istruzione. Per estrarre un valore dallo stack, POPviene utilizzata l' istruzione.
Esempio : supponendo che SS = 1000h e SP = 0xF820. Ciò significa che la parte superiore dello stack corrente è l'indirizzo fisico 0x1F820 (ciò è dovuto alla segmentazione della memoria in 8086 ). Le prossime due istruzioni macchina del programma sono:
PUSH AX
PUSH BX
- Questa prima istruzione inserisce nello stack il valore memorizzato in AX (registro a 16 bit). Questo viene fatto sottraendo un valore di 2 (2 byte) da SP.
- Il nuovo valore di SP diventa 0xF81E. La CPU quindi copia il valore di AX nella parola di memoria il cui indirizzo fisico è 0x1F81E.
- Quando viene eseguito "PUSH BX", SP è impostato su 0xF81C e BX viene copiato su 0x1F81C.
Questo illustra come funziona PUSH. Di solito, il programma in esecuzione inserisce i registri nello stack per utilizzare i registri per altri scopi, come chiamare una routine che può modificare i valori correnti dei registri. Per ripristinare i valori memorizzati nello stack, il programma deve contenere istruzioni macchina come queste:
POP BX
POP AX
-
POP BXcopia la parola su 0x1F81C (che è il vecchio valore di BX) in BX, quindi aumenta SP di 2. SP ora è 0xF81E. -
POP AXcopia la parola su 0x1F81E su AX, quindi imposta SP su 0xF820.
Stack engine
I processori più semplici memorizzano il puntatore dello stack in un normale registro hardware e utilizzano l' unità logica aritmetica (ALU) per manipolare il suo valore. Tipicamente push e pop vengono tradotti in più micro-operazioni , per aggiungere / sottrarre separatamente il puntatore allo stack ed eseguire il caricamento / archiviazione in memoria.
I processori più recenti contengono un motore stack dedicato per ottimizzare le operazioni dello stack. Pentium M è stato il primo processore x86 a introdurre un motore stack. Nella sua implementazione, lo stack pointer è suddiviso in due registri: ESP O , che è un registro a 32 bit, e ESP d , un valore delta a 8 bit che viene aggiornato direttamente dalle operazioni di stack. Gli opcode PUSH, POP, CALL e RET operano direttamente con il registro ESP d . Se ESP d è vicino all'overflow o il registro ESP è referenziato da altre istruzioni (quando ESP d ≠ 0), viene inserita una micro-op di sincronizzazione che aggiorna l'ESP O utilizzando l'ALU e reimposta ESP d a 0. Questo design è rimasto in gran parte non modificato nei successivi processori Intel, sebbene ESP O sia stato ampliato a 64 bit.
Nella microarchitettura AMD K8 è stato adottato anche uno stack engine simile a quello di Intel . In Bulldozer , la necessità di micro-operazioni di sincronizzazione è stata rimossa, ma il design interno del motore dello stack non è noto.