Perché un puntatore del frame è impostato come offset dal puntatore dello stack? [duplicare]

3

Sto cercando di capire come vengono costruiti i frame di stack e sono stati inseriti in questa descrizione su wikipedia:

The locations of all other fields in the frame can be defined relative either to the top of the frame, as negative offsets of the stack pointer, or relative to the top of the frame below, as positive offsets of the frame pointer. The location of the frame pointer itself must inherently be defined as a negative offset of the stack pointer. --- https://en.wikipedia.org/wiki/Call_stack

La descrizione nella citazione sopra implica che l'indirizzo del puntatore del frame è un offset dal puntatore dello stack è banalmente ovvio dalle rispettive definizioni.

Sono confuso sul motivo per cui la posizione del puntatore del frame deve essere intrinsecamente definita come una funzione del puntatore dello stack.

Come ho capito la situazione, il puntatore dello stack viene incrementato quando viene assegnata una nuova memoria al frame. Tuttavia, la posizione del puntatore del frame viene fissata dal punto in cui è terminato il prologo della procedura.

Poiché tutti gli accessi alla memoria all'interno del frame devono essere indirizzati come offset dal puntatore del frame o come offset di memoria dal puntatore dello stack e uno dei puntatori del frame e dello stack è una posizione fissa e l'altro è intrinsecamente mutabile, sicuramente ha senso rendere il puntatore mutabile un offset dal puntatore fisso?

A quanto ho capito, nello schema sopra, dovresti aggiornare il riferimento del puntatore del frame ogni volta che hai incrementato il puntatore dello stack, il che sembra eccessivo. Che cosa ho frainteso?

    
posta Racheet 24.11.2015 - 14:37
fonte

1 risposta

7

Bene, hai ragione, è tutto molto confuso. Prima di tutto, il puntatore del frame non è nemmeno necessario. Tutto è indirizzabile usando solo il puntatore dello stack.

Il motivo principale dell'esistenza del puntatore del frame è che il valore del puntatore dello stack può cambiare durante l'esecuzione della funzione, ovvero quando si inseriscono nello stack i parametri di altre funzioni che si è disposti a chiamare ,) significa che l'offset di ogni argomento e ogni locale varierà. Questo non è un problema per un compilatore, che può semplicemente tenere traccia di come varia il puntatore dello stack e utilizzare di conseguenza gli offset regolati, ma può diventare un incubo per un umano che sta cercando di scrivere la funzione o eseguirne il debug in seguito. / p>

Un altro motivo per cui esiste il puntatore del frame è storico: l'architettura Intel x86 era un po 'scomoda per quanto riguarda l'indirizzamento della memoria rispetto al puntatore dello stack. Gli unici registri che potevano essere usati come registri indice erano BX, BP, SI e DI, nota come SP manca dall'elenco. Pertanto, il registro BP è stato utilizzato come puntatore del frame. Tuttavia, è un po 'strano che l'articolo di Wikipedia debba essere influenzato dall'8086, perché sta descrivendo uno stack che cresce verso l'alto, mentre sull'architettura x86 lo stack cresce verso il basso. Vai a capire.

Notare che questo è stato corretto in x64. Se si consulta il supplemento del processore di architettura AMD64 per l'interfaccia binaria di System V Application , a pagina 16 c'è una nota a piè di pagina che dice:

The conventional use of %rbp as a frame pointer for the stack frame may be avoided by using %rsp (the stack pointer) to index into the stack frame. This technique saves two instructions in the prologue and epilogue and makes one additional general-purpose register (%rbp) available.

Quindi, in poche parole, l'uso convenzionale del puntatore del frame è il seguente: quando si accede a una funzione, il puntatore del frame riceve una copia del valore del puntatore stack e il puntatore dello stack viene regolato per fare spazio a i locali. Quindi, durante l'esecuzione della funzione, il puntatore allo stack può variare, ma il puntatore del frame rimane costante, quindi gli argomenti e le persone locali sono ancora indirizzabili con offset fissi dal puntatore del frame.

Per tornare alla domanda, la posizione del puntatore del frame non è esattamente definita come una funzione del puntatore dello stack, nel senso che il valore del puntatore dello stack viene copiato nel puntatore del frame solo una volta, all'inizio di la funzione. Da quel momento in poi, il puntatore del frame rimane costante, mentre il puntatore dello stack varia.

    
risposta data 24.11.2015 - 15:27
fonte

Leggi altre domande sui tag