Os programadores podem ter perguntas sobre os quadros de pilha não em um termo amplo (que é uma entidade única na pilha que serve apenas uma chamada de função e mantém o endereço de retorno, argumentos e variáveis locais), mas em um sentido restrito - quando o termo stack frames
é mencionado em contexto das opções do compilador.
Se o autor da pergunta quis dizer isso ou não, mas o conceito de um quadro de pilha do aspecto das opções do compilador é uma questão muito importante, não abordada pelas outras respostas aqui.
Por exemplo, o compilador C / C ++ do Microsoft Visual Studio 2015 tem a seguinte opção relacionada a stack frames
:
- / Oy (omissão de ponteiro de quadro)
O GCC tem o seguinte:
- -fomit-frame-pointer (Não mantenha o ponteiro de quadro em um registro para funções que não precisam de um. Isso evita as instruções para salvar, configurar e restaurar ponteiros de quadro; também disponibiliza um registro extra em muitas funções )
O compilador Intel C ++ possui o seguinte:
- -fomit-frame-pointer (Determina se o EBP é usado como um registro de uso geral em otimizações)
que tem o seguinte alias:
O Delphi tem a seguinte opção de linha de comando:
- - $ W + (Gerar quadros de pilha)
Nesse sentido específico, da perspectiva do compilador, um quadro de pilha é apenas o código de entrada e saída da rotina , que lança uma âncora na pilha - que também pode ser usada para depuração e manipulação de exceções. As ferramentas de depuração podem varrer os dados da pilha e usar essas âncoras para rastreamento, enquanto localizam call sites
na pilha, ou seja, para exibir os nomes das funções na ordem em que foram chamadas hierarquicamente. Para a arquitetura Intel, é push ebp; mov ebp, esp
ou enter
para entrada e / mov esp, ebp; pop ebp
ou leave
saída.
É por isso que é muito importante entender para um programador qual é o quadro de uma pilha quando se trata de opções do compilador - porque o compilador pode controlar se deseja gerar esse código ou não.
Em alguns casos, o quadro da pilha (código de entrada e saída da rotina) pode ser omitido pelo compilador e as variáveis serão acessadas diretamente pelo ponteiro da pilha (SP / ESP / RSP), em vez do conveniente ponteiro base (BP / ESP / RSP). Condições para omissão do quadro da pilha, por exemplo:
- a função é uma função folha (isto é, uma entidade final que não chama outras funções);
- não há tentativa / finalmente ou tentativa / exceto construções semelhantes, ou seja, nenhuma exceção é usada;
- nenhuma rotina é chamada com parâmetros de saída na pilha;
- a função não possui parâmetros;
- a função não possui código de montagem embutido;
- etc ...
A omissão de quadros de pilha (código de entrada e saída para a rotina) pode tornar o código menor e mais rápido, mas também pode afetar negativamente a capacidade dos depuradores de rastrear os dados na pilha e exibi-los ao programador. Essas são as opções do compilador que determinam sob quais condições uma função deve ter o código de entrada e saída, por exemplo: (a) sempre, (b) nunca, (c) quando necessário (especificando as condições).