I programmatori possono avere domande sui frame dello stack non in senso lato (che si tratta di un'entità singola nello stack che serve solo una chiamata di funzione e mantiene l'indirizzo di ritorno, argomenti e variabili locali) ma in senso stretto - quando il termine stack frames
è menzionato in contesto delle opzioni del compilatore.
Se l'autore della domanda lo abbia o meno significato, ma il concetto di stack frame dall'aspetto delle opzioni del compilatore è un problema molto importante, non trattato dalle altre risposte qui.
Ad esempio, il compilatore C / C ++ di Microsoft Visual Studio 2015 ha la seguente opzione relativa a stack frames
:
- / Oy (Omissione del puntatore al telaio)
GCC ha il seguente:
- -fomit-frame-pointer (Non tenere il puntatore del frame in un registro per le funzioni che non ne hanno bisogno. Questo evita le istruzioni per salvare, impostare e ripristinare i puntatori del frame; rende anche disponibile un registro extra in molte funzioni )
Il compilatore Intel C ++ ha il seguente:
- -fomit-frame-pointer (Determina se l'EBP viene utilizzato come registro per scopi generici nelle ottimizzazioni)
che ha il seguente alias:
Delphi ha la seguente opzione da riga di comando:
- - $ W + (Genera frame stack)
In questo senso specifico, dal punto di vista del compilatore, un frame dello stack è solo il codice di entrata e uscita per la routine , che spinge un ancoraggio nello stack - che può anche essere usato per il debug e per la gestione delle eccezioni. Gli strumenti di debug possono scansionare i dati dello stack e usare questi ancoraggi per il backtracing, mentre si trovano call sites
nello stack, cioè per visualizzare i nomi delle funzioni nell'ordine in cui sono stati chiamati gerarchicamente. Per l'architettura Intel, è push ebp; mov ebp, esp
o enter
per entrata e / mov esp, ebp; pop ebp
o leave
uscita.
Ecco perché è molto importante capire per un programmatore in cosa si trova un frame di stack quando si tratta di opzioni del compilatore, perché il compilatore può controllare se generare questo codice o meno.
In alcuni casi, il compilatore può omettere il frame dello stack (codice di entrata e uscita per la routine) e sarà possibile accedere direttamente alle variabili tramite il puntatore dello stack (SP / ESP / RSP) anziché il comodo puntatore di base (BP / ESP / RSP). Condizioni per l'omissione del frame dello stack, ad esempio:
- la funzione è una funzione foglia (cioè un'entità finale che non chiama altre funzioni);
- non ci sono costrutti try / finally o try / tranne o simili, ovvero non vengono utilizzate eccezioni;
- non vengono chiamate routine con parametri in uscita nello stack;
- la funzione non ha parametri;
- la funzione non ha un codice assembly incorporato;
- eccetera...
L'omissione di frame di stack (codice di entrata e di uscita per la routine) può rendere il codice più piccolo e più veloce, ma può anche influire negativamente sulla capacità dei debugger di risalire ai dati nello stack e mostrarli al programmatore. Queste sono le opzioni del compilatore che determinano a quali condizioni una funzione dovrebbe avere il codice di entrata e uscita, ad esempio: (a) sempre, (b) mai, (c) quando necessario (specificando le condizioni).